JS动态规划——青蛙跳台阶问题

JavaScript027

JS动态规划——青蛙跳台阶问题,第1张

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

此类求 多少种可能性 的题目一般都有 递推性质 ,即 f(n)f(n) 和 f(n-1)f(n−1)…f(1)f(1) 之间是有联系的。

设跳上 n 级台阶有 f(n) 种跳法。在所有跳法中,青蛙的最后一步只有两种情况: 跳上 1 级或 2 级台阶。

当为 1 级台阶: 剩 n-1 个台阶,此情况共有 f(n-1) 种跳法;

当为 2 级台阶: 剩 n-2 个台阶,此情况共有 f(n-2) 种跳法。

f(n) 为以上两种情况之和,即 f(n)=f(n-1)+f(n-2) ,以上递推性质为斐波那契数列。本题可转化为 求斐波那契数列第 n 项的值 。

青蛙跳台阶问题: f(0)=1 , f(1)=1 , f(2)=2,;

斐波那契数列问题: f(0)=0 , f(1)=1 , f(2)=1 。

第n阶的数量由前两阶的数量相加而来,故用动态规划。

arr[i]表示第i阶有arr[i]种方法

递推公式:arr[i] = arr[i - 1] + arr[i - 2]

arr数组初始化:arr = [null, 1, 2],arr[0]没有意义,从i=3开始循环

遍历顺序:从前往后

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

因为n级台阶,第一步有n种跳法:跳1级、跳2级、到跳n级 跳1级,剩下n-1级,则剩下跳法是f(n-1) 跳2级,剩下n-2级,则剩下跳法是f(n-2) 所以f(n)=f(n-1)+f(n-2)+...+f(1) 因为f(n-1)=f(n-2)+f(n-3)+...+f(1) 所以f(n)=2*f(n-1)

如果target = 0,说明是直接跳过来,否则返回1;否则,总是有target中选择,把每种选择包含的步骤起来就行了,递归到0结束循环,并合并结果。

原文链接: http://blog.csdn.net/qq_22329521/article/details/52967839

递归由于调用自身,而函数调用是有时间和空间的消耗的:每一次函数调用,都需要在内存栈中分配内存空间以保存参数、返回地址及临时变量,而且往栈里压入数据和弹出数据都需要时间。

另外,递归中有可能很多计算都是重复的,从而对性能带来很大的负面影响。递归的本质是把一个问题分解成两个或者多个小问题。如果多个小问题存在互相重叠的部分,那么久存在重复的计算。

斐波那契数列

效率最低的解法

青蛙跳题目(扩展)

一只青蛙一次可以跳上一个台阶,也可以跳上2个台阶,求青蛙跳上一个n级台阶共有多少总跳法

思路:如果只有1级台阶,显然只有一种跳法,如果两个台阶,就来有种跳法

一般情况下,我们把n级台阶时的跳法看成是n的函数,记为f(n)。当n>2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1)另一种选择是第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目即为f(n-2)因此n级台阶的不同跳法总数是f(n)=f(n-1)+f(n-2)

青蛙跳扩展2

如果一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。。。它也可以跳上n级台阶,此时青蛙跳上一个n级台阶共有集中跳法,用数学的归纳法可以证明是f(n)=2^{(n-1)}

格子覆盖问题(扩展)

我们可以用2x1 的小矩形横着或者竖着去覆盖更大的矩形如8个2x1 的小矩形无重叠的覆盖一个2x8的大矩形,共有几种方法

思路:我们先把2x8的覆盖方法记为f(8)用第一个1x2小矩形去覆盖大矩形的最左边两个选择,竖着或者横着放,当竖着放,右边还剩下2x7的区域,它的覆盖方法即为f(7)。然后考虑横着放的情况。当1x2的小矩形横着放在左上角的时候,左下角必须和横着放一个1x2的小矩形,而在右边还剩下2x6的区域,这种情形下的覆盖方法记为f(6),因此f(8)=f(7)+f(6)也是个斐波那契数列