青蛙跳台阶
引言
首先,我们写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。
斐波那契(Fibonacci)数列定义如下:
代码实现
递归方式:
int fibnacci(int n){
if (n==0){
return 0;
}
if (n==1){
return 1;
}
return fibnacci(n-1)+fibnacci(n-2);
}
非递归方式:
int Fibonacci(int n)
{
int res[2] = {0 , 1};
if(n < 2)
return res[n];
int fibMinusOne = 1;
int fibMinusTwo = 0;
int fibN=0;
for(int i = 3 ; i <= n ; ++i)
{
fibN = fibMinusOne + fibMinusTwo;
fibMinusTwo = fibMinusOne;
fibMinusOne = fibN;
}
return fibN;
}
五大经典例题
- 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶,……他也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法?
状态:F(i):跳上i级台阶的方法数
F(1):一个台阶:1 方法数:1
F(2):两个台阶:1,1 2
2
F(3):三个台阶:1,1,1 4
1,2
2,1
3
F(4):四个台阶:1,1,1,1 8
1,1,2
1,2,1
2,1,1
2,2
1,3
3,1
4
状态转移方程推导: (F(0) = 1)
- F(i) = F(i - 1)+F(i - 2)+F(i - 3)+…+F(0)
- F(i - 1) = F(i - 2) + F(i - 3) +…+ F(0)
- F(i) = F(i - 1) + F(i - 1) = 2i-1
- 限制青蛙一次最多只能跳上2级台阶:
F(i) = F(i - 1) + F(i - 2)
也可以这样理解:小青蛙想跳到第n阶台阶必须经过n-1或n-2阶台阶(小青蛙每次只能跳一阶或两阶),则问题转化为n阶台阶的跳法总数为n-1和n-2台阶的跳法总数之和,故表达式f(n)=f(n-1)+f(n-2)是非常正确的结论。
- 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个m级的台阶总共有多少种跳法。
先列多项式:
- f(n) = f(n-1) + f(n-2) + f(n-3) + … + f(n-m)
- f(n-1) = f(n-2) + f(n-3) + … + f(n-m) + f(n-m-1)
化简得:f(n) = 2f(n-1) - f(n-m-1)
int Jump(int n,int m ) {
// 当m小于n的时候就是上面的公式
if(n > m){
return 2*Jump(n-1, m)-Jump(n-1-m, m);
}
// 当m大于等于n的时候是和n级的相同了
if (n <= 1) {
return 1;
} else {
return 2 * Jump(n - 1,n);
}
}
- 用2 * 1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2 * 1的小矩形无重叠地覆盖一个2 * n的大矩形,总共有多少种方法
状态转移方程推导:
- 若第一块矩形竖着放,后边还有n-1个2 * 1 小矩形去组成2 * (n-1)矩形,即此种情况下,有f(n-1)种覆盖方法。
- 若两块横着放,后边还有n-2个2 * 1 小矩形去组成2*(n-2)矩形,此种情况下,有f(n-2)种覆盖方法。
- 可得
f(n)=f(n-1)+f(n-2)
- 求最大连续子数组和{6,-3,-2,7,-15,1,2,2}
状态F(i):以第i个元素结尾的连续最大和
F(0):{6}
F(1):{6,-3},{-3}
F(2):{6,-3,-2},{-3,-2},{-2}
F(3):{6,-3,-2,7},{-3,-2,7},{-2,7},{7}
F(i) = Max(F(i - 1) + array[i], array[i])
- F(i - 1):状态F(i)前的状态结果
- array[i]:数组的第i个下标对应的数字
返回值:Max(F(i))
如有不同见解,欢迎留言讨论~~