版权声明:转载请注明出处 https://blog.csdn.net/zhouchen1998/article/details/88726156
爬楼梯问题
-
动态规划
- 动态规划算法将带求解问题拆分成一系列相互交叠的子问题,通过递推关系定义各子问题的求解策略,并随时记录子问题的解,最终获得原始问题的解,避免了对交叠子问题的重复求解。
- 在动态规划算法中有三要素,即最优子结构、边界和状态转移函数。
- 最优子结构是指每个阶段的最优状态可以由之前某个阶段的某个或某些状态直接得到。
- 边界是指问题最小子集的解;(代码中就是递归的出口)
- 状态转移函数是指从一个阶段向另一个阶段过渡的具体模式,描述的是两个相邻子问题之间的关系。
- 凡是具有这三个要素的问题均可以使用动态规划求解。
- 本案例是一个简单基础的问题—爬楼梯问题。
-
问题描述
- 假设小明要怕一个10级的楼梯,一步走一级或者一步走两级,问他走到顶有多少种方法。
- 举个例子,他可以每次走一步,那么他走了10步;他也可以一次走两步,他走了5步;解题的人要找到所有走的方案。
-
问题分析
- 不妨直接看最后一步,他要么是从第九级再走一级到顶,要么是从第八级走两步到顶。
- 也就是说,最后那一步要么从第九级出发(这时只有唯一路径,就是走一级);要么从第八级出发(这时只有唯一路径,走两级;如果走两个一级,那么这种情况就是第一种的内容了)。
- 换句话说,一旦知道从地面到第八级有X种走法,从地面到第九级有Y种走法,那么从地面到顶就是X+Y种走法。
- 为了方便描述,用F(n)表示第n级台阶的走法数量,可知F(10)=F(9)+f(8)。推广一下,就是F(n)=F(n-1)+F(n-2)。这就是我们想要的状态转移函数和最优子结构
- 当问题细化,只有一级台阶和两级台阶时,不再细化,F(1)=1,F(2)=2。这就是边界
- 该问题动态规划解法的三要素全都出现了
- 边界:F(1)=1,F(2)=2
- 最优子结构:F(n-1)和F(n-2)
- 状态转移函数:F(n)=F(n-1)+F(n-2)
- 这个问题的动态规划建模完成了,为了时间和空间的效率(特别对于大问题),利用最优子结构的特性,采用自底向上的方式计算。
- 也就是根据1、2算3,根据2、3算4,以此类推。
-
代码
-
def upstairs(n): if n < 1: return 0 if n == 1: return 1 if n == 2: return 2 if n > 2: return upstairs(n-1) + upstairs(n-2) for i in range(1, 11): print("到第{}级的方案有{}种".format(i, upstairs(i)))
-
-
补充说明
- 具体代码可以查看我的Github,欢迎Star或者Fork
- 参考书《你也能看得懂的Python算法书》