问题: 楼梯有n阶台阶,一步可以走1个、2个或者3个台阶,一共有多少种上楼梯的方法?
代码实现:
#include<iostream>
using namespace std;
int cnt=0;//用于计数
void f(int n)//n表示还剩你个台阶需要走
{
if(n<0) return; //防止死循环
if(n==0)
{
cnt++;
return;
}
f(n-1); //走一步
f(n-2); //走两步
f(n-3); //走三步
}
int main()
{
int n;
cin>>n;
f(n);
cout<<cnt;
return 0;
}
缺陷: 当n比较大时,耗时巨大甚至可能爆栈。分析可知,在上述的递归中存在大量的重复子问题,做了大量的无用功。为了解决重复子问题,可以使用记忆型的递归进行优化。
代码实现:
#include<iostream>
using namespace std;
int dp[1001];//假设楼梯的台阶数可以达到1000
int f(int n)//n表示还剩你个台阶需要走
{
if(n<0) return 0; //防止死循环,要放在前面,防止dp角标小于0
if(dp[n]!=0) return dp[n];
int cnt=0;//用于计数
if(n==0)
{
cnt++;
return cnt;
}
cnt+=f(n-1); //走一步
cnt+=f(n-2); //走两步
cnt+=f(n-3); //走三步
dp[n]=cnt;
return cnt;
}
int main()
{
int n;
cin>>n;
cout<<f(n);
return 0;
}
递推迭代的方法: 常规的正向思维。
代码实现:
#include<iostream>
using namespace std;
int f(int n)
{
if(n<=0) return 0;
if(n==1) return 1;
if(n==2) return 2;
if(n==3) return 4;
int x1=1,x2=2,x3=4;
for(int i=4;i<=n;i++) //迭代
{
int temp=x1;
x1=x2;
x2=x3;
x3=temp+x1+x2;
}
return x3;
}
int main()
{
int n;
cin>>n;
cout<<f(n);
return 0;
}