题目:一个台阶总共有 n 级,如果一次可以跳 1 级,也可以跳 2 级。
求总共有多少总跳法,并分析算法的时间复杂度。
我们把 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-2)。n=1时,只有一种跳法,f(n)=1;n=2时,f(n)=2。
/ 1 n=1
f(n) = 2 n=2
\ f(n-1) + f(n-2) n>2
下面两种方法实现:
1、递归方法:从上往下计算,递归方法简单,但是要重复计算,很慢。
//递归,很慢,因为要重复计算。随n成指数级上涨
int f(int n)
{
if(n==1)
return 1;
if(n==2)
return 2;
return f(n-1)+f(n-2);
}
//非递归。当前值=第前1个值+第前2个值,速度快,不需要重复计算
int f2(int n)
{
if(n==1||n==2)
return n;
int fi=0,f1=2,f2=1;//fi代表f(n),f1代表f(n-1),f2代表f(n-2)
for(int i=3;i<=n;i++)
{
fi=f2+f1;
f2=f1;//更新f1,f2
f1=fi;
}
return fi;
}
还有O(logn)的算法,详见http://blog.youkuaiyun.com/dadoneo/article/details/6776272 “ O(logn)时间复杂度求Fibonacci数列”
类似的题目:一个人上台阶可以一次上 1 个,2 个,或者 3 个, 问这个人上 n 层的台阶,总共有几种走法?
代码如下:
<span style="font-size:18px;">#include <iostream>
#include <bitset>
using namespace std;
//递归,很慢,因为要重复计算。随n成指数级上涨
int f(int n)
{
if(n==1)
return 1;
if(n==2)
return 2;
if(n==3)
return 4;
return f(n-1)+f(n-2)+f(n-3);
}
//非递归。当前值=第前1个值+第前2个值,速度快,不需要重复计算
int f2(int n)
{
if(n==1||n==2)
return n;
if(n==3)
return 4;
int fi=0,f1=4,f2=2,f3=1;//fi代表f(n),f1代表f(n-1),f2代表f(n-2),f3代表f(n-3)
for(int i=4;i<=n;i++)
{
fi=f3+f2+f1;
f3=f2;//更新f1,f2,f3
f2=f1;
f1=fi;
}
return fi;
}
int main()
{
int n=0;
cin>>n;
while(n!=-1)
{
cout<<f2(n)<<endl;
cout<<f(n)<<endl;
cin>>n;
}
system("pause");
} </span>