爬楼梯
每步可跨台阶:1,2,3 —该场景表示有序组合
台阶总数:15
求多少种跨法

'''
倒推下,当我倒数第二步已经走了14、13或12步时,我最后一步就可以就可以走完15个台阶此时我15步的走法跟最后一步无关,而是跟前面的三种结果有关,即是12+13+14步的走法和
由此再分别倒推14/13/12三种情况的走法,得到是13+12+11和12+11+10和11+10+9九种情况的走法和
....
在分解到最后,你就会发现是多个1/2/3走法的和
以F表示走法的函数,i表示台阶总数,F(i-1)、F(i-2)、F(i-3)分别表示最后一步为1/2/3的情况
即 F(i) = F(i-1)+F(i-2)+F(i-3)
我们建立一个数组,以下标表示总台阶数,则长度为n+1,再在每一个坐标元素上设置值为对应的总走法数
即有 [0,1,2,4,
'''
n = 15
steps = [1, 2, 3]
list_a = [0] * (n + 1)
list_a[0] = 1  # 总台阶数为0时0种走法,但是为了后面好进行迭代,我们设置为1,
list_a[1] = 1  # 总台阶数为1时只有[{1}]这一种走法,使用公式应为 f[0]的走法与最后一步为1的走法的组合
list_a[2] = 2  # 总台阶数为2时有[{1,1},{2}]这2种走法,使用公式应为 f[1]的走法与最后一步为1的走法的组合加上f[0]与最后一步为2的走法的组合
list_a[3] = 4  # [{1,1,1},{1,2},{2,1},{3}]
list_a[4] = 7  # [{1,1,1,1},{1,2,1},{2,1,1},{3,1},  {1,1,2}{2,2},  {1,3} ]
#上面是一个介绍过程,使用循环我们可以写成:
list_b = [0] * (n + 1)
list_b[0] = 1  # 初始化,方便计算,正常应该是0的
for i in range(1, n + 1):  # 循环给每一总台阶为i时计算走法for s in steps:  # 计算总台阶为i时最后一步为 s的走法if i >= s:  # 必须总台阶数大于步数才有走法list_b[i] += list_b[i - s]  # 总台阶数为 i时计算各个最后一步为s的走法的和
print(list_b[1])
print(list_b[2])
print(list_b[3])
print(list_b[4])
print(list_b[5])
print(list_b[6])
print(list_b[15])
C:\Python39\python.exe D:/PyWork/test_script/leetcode20220212.py
1
2
4
7
13
24
5768

凑金额
硬币面值:1,2,5 —这种场景与爬楼梯不一样,你在挑选时可以1,2,1或2,1,1的凑出4块钱,但是最后还是只算一种组合方式。
此时需要用背包算法来进行考虑
总金额:15
求组合方式

'''
背包算法就是指一堆指定面额/体积/重量的物品放入背包,求最大数量/方法/价值等内容的算法
如果物品每样只有一个就是0,1背包,方或者不放;不限制数量就是完全背包
这个场景就是不限制物品数量的场景
无序的话我们就不考虑取硬币的顺序而是考虑取硬币的数量。
我们可以用dp表(dynamic programming动态规划)表来进行推算总金额 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |   # 下面的行往下一次表示只有1面额,有1和2面额,有1,25三种面额的情况1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |   #这行表示在只有1这一种面值的情况下,此时只会有一种组合方式
面额 2 | 1 | 1 | 2 | 2 | 3 | 3 | 4 | 4 | 5 | 5 |       #这行表示只有1和2两种面额时的场景5 | 1 | 1 | 2 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |         #这行表示有1,2,5三种面额的场景
金额为0时,没有组合方式
当我们只选择面值为1(i=0)的硬币时,不管总金额j>0为多少,只有一种组合方式,就是全部取面额为1的硬币,得到 dp[0][j]=1
当我们选择取面值为1/2两种硬币时,有不取2面额的取法,有取2面额的取法。当总金额每增加2,面额2就可以增加1,取法数也增加1
跟上面爬楼梯的思考方式类似,在同金额面值不同总金额的条件下发现也有F[i][j] = F[i][j-coins[i])+1的算法,
在不同面值同金额时就是F[i][j] = F[i-1][j]+j//coins[i]
我们可以先循环总金额(意思是以面额为外层,里面为金额,先循环完里面再循环一次外面),再循环面值
'''
coins = [1, 2, 5]
n = 15
dp = [[0] * (n + 1) for i in range(len(coins))]  # 初始化dp表
for i in range(n + 1):dp[0][i] = 1  # 第一行只有一个面额硬币,组合始终是1
for j in range(len(coins)):dp[j][0] = 1  # 初始第1化列,为了方便迭代作为1
[print(i) for i in dp]  # 可以看看初始化的dp表
for i in range(1, len(coins)):  # 遍历币种,第一种全是1就跳过了for j in range(1, n + 1):  # 先循环金额if j >= coins[i]:  # 考虑1块钱时没有往前退两块到-1的场景。这个条件主要在i小于2和小于5时对对应的2/5面值生效dp[i][j] = dp[i][j - coins[i]] + dp[i - 1][j]# dp[i - 1][j]表示不取i币种时的取法,dp[i][j - coins[i]]表示取i币种时(你可以看最后的打印dp[2][8]和dp[2][3],8金额的取法就是在3金额的取法后面各加了一个5面值,取法数不变的)else:  # 金额要大于币种才计算,1块钱时使用2块的面额用不了,此时只有1块的取法dp[i][j] = dp[i - 1][j]
print("========================完成计算后的dp表============")
[print(i) for i in dp]
print(dp[2][1])  # 1 [{1}]
print(dp[2][2])  # 2 [{1,1},{2}]
print(dp[2][3])  # 2 [{1,1,1},{1,2}]
print(dp[2][4])  # 3 [{1,1,1,1},{1,1,2},{2,2}]
print(dp[2][5])  # 4 [{1,1,1,1,1},{1,1,1,2},{1,2,2},{5}]
print(dp[2][6])  # 5 [{1,1,1,1,1,1},{1,1,1,1,2},{1,1,2,2},{2,2,2},{1,5}]
print(dp[2][7])  # 6 [{1,1,1,1,1,1,1},{1,1,1,1,1,2},{1,1,1,2,2},{1,2,2,2},{1,1,5},{2,5}]
print(dp[2][8])  # 7 [{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,2},{1,1,1,1,2,2},{1,1,2,2,2},{2,2,2,2},{1,1,1,5},{1,2,5}]
print(dp[2][15])
C:\Python39\python.exe D:/PyWork/test_script/leetcode20220212.py
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
========================完成计算后的dp表============
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8]
[1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 10, 11, 13, 14, 16, 18]
1
2
2
3
4
5
6
7
18

动态规划算法学习(一)爬楼梯和凑金额相关推荐

  1. 算法:Climbing Stairs(爬楼梯) 6种解法

    说明 算法:Climbing Stairs(爬楼梯) LeetCode地址:https://leetcode.com/problems/climbing-stairs/ 题目: You are cli ...

  2. 动态规划/滚动数组/通项公式——爬楼梯

    一.题目 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 二.思路解析 1.迭代 第n个台阶只能从第n-1或者n-2个上来.到第 ...

  3. 动态规划——使用最小花费爬楼梯(Leetcode 746)

    题目选自Leetcode 746.使用最小花费爬楼梯 题目描述: 解题代码:C语言 int minCostClimbingStairs(int* cost, int costSize) {int pr ...

  4. 程序设计与算法----递归之爬楼梯问题

    爬楼梯 树老师爬楼梯,它可以每次走1级或者2级,输入楼梯的级数,求不同的走法数 例如:楼梯一共有3级,它可以每次都走一级,或者第一次走一级,第二次走两级,也可以第一次走两级,第二次走一级,一共有3种走 ...

  5. 一步一步写算法(之爬楼梯)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前两天上网的时候看到一个特别有意思的题目,在这里和朋友们分享一下: 有一个人准备开始爬楼梯,假 ...

  6. LeetCode动态规划 使用最小花费爬楼梯

    数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始). 每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶 ...

  7. 神奇的口袋(动态规划)--算法学习

    问题描述 有一个神奇的口袋,总的容积是40,用这个口袋可以变出 一些物品,这些物品的总体积必须是40.  John现在有n(1≤n ≤ 20)个想要得到的物品,每个物品 的体积分别是a1,a2--a ...

  8. 动态规划算法学习二:最长公共子序列

    文章目录 前言 一.问题描述 二.DP实现 1.最优子结构性质***** 2.状态表示***** 3.状态递归方程***** 4.计算最优值***** 5.代码实现:输出最长公共子序列 6.代码实现: ...

  9. 滑雪(动态规划)--算法学习

    问题描述 Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激. 可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底, 你不得不再次走上坡或者等待升降机来载你. Michael想知道载一个区 ...

最新文章

  1. 解决putty中文乱码并远程访问linux界面功能
  2. 用两张图告诉你,为什么你的App会卡顿?
  3. inputstreamreader未关闭会导致oom_Linux内核OOM机制分析和防止进程被OOM杀死的方法...
  4. asp.net处理机制管道事件
  5. Hive建表与数据加载
  6. 2007年IT技术走向何方 网络将再掀“酷”革命
  7. jQuery扩展半Lambda表达式 类似Linq的Where
  8. adminlte3 动态菜单_一本科学菜单,十倍利润增长 | 跟巴奴学餐饮业的精简风:菜单越薄,利润越厚!...
  9. Grub 开启serial console支持
  10. JAVA项目在服务器部署过程
  11. 和“目标”相关的名言
  12. ComposeOptions.kotlinCompilerVersion is deprecated
  13. 为什么选择高防DNS云解析?(二)
  14. win7截屏快捷键未在计算机上运行,修复win7“截图工具当前未在计算机上运行”的方法...
  15. 2011-12-24
  16. 数据库删改都不会,还能被录用:女程序员要求这么宽松?
  17. 一个疯子的梦-20190921
  18. mysql 去除微秒_mysql的微秒补丁 - sihanjishu的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  19. 搜狗广告联盟不显示广告的原因
  20. python天气查询_python天气查询

热门文章

  1. 中国联通将 900MHz 频段频谱资源重耕用于 5G 系统,更有利用把5G网络覆盖到边远地区的每一寸土地
  2. 玩转AgiileCDN(十三)——全站加速
  3. ubuntu环境下增加-pie选项导致可执行程序无法通过双击启动的问题
  4. 沧海一声笑(最好版):也论智能的生成
  5. 台湾SSS鑫创SSS1700替代Cmedia CM6533 24bit 96KHZ USB音频编解码芯片
  6. R语言while循环计算圆周率
  7. java后台跳转页面实现方式
  8. Apollo学习笔记1-ESD_CAN调试
  9. Router-Link详解
  10. 大数据技能修炼的个人道场