题目描述
1190:上台阶
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 28183 通过数: 8429
【题目描述】
楼梯有n(71>n>0)阶台阶,上楼时可以一步上1阶,也可以一步上2阶,也可以一步上3阶,编程计算共有多少种不同的走法。
【输入】
输入的每一行包括一组测试数据,即为台阶数n。最后一行为0,表示测试结束。
【输出】
每一行输出对应一行输入的结果,即为走法的数目。
【输入样例】
1
2
3
4
0
【输出样例】
1
2
4
7
算法1
(暴力枚举)
#include <cstdio>
using namespace std;
const int mod = 1000 ;
int n, x ;
inline int fib(int x){
if(x == 1 || x == 2) return 1;
return fib(x-1) % mod + fib(x - 2) % mod;
}
int main(){
scanf("%d",&n);
while(n--){
scanf("%d",&x);
printf("%d\n",fib(x) % mod);
}
return 0;
}
每次找一个fib书都要重新递归,递归深度很大,时间空间消耗都非常大,直接爆掉(这里一个都过不了)(太惨了)
所以我们需要改进代码,方法主要有一下两种:
1.既然递归深度这么大,就干脆不要递归了,递推!!
2.记忆化递归,减少递归深度
//记忆化
#include <cstdio>
using namespace std;
const int mod = 1000;
const int MAXN = 1000000;
int n , f[MAXN + 1], x;
int fib(int x){
if(!f[x]) return f[x] = (fib(x-1) + fib(x-2)) % mod; // 已经存储过了就不用再找了
return f[x];
}
int main(){
scanf("%d",&n);
f[1] = f[2] = 1;
while(n--){
scanf("%d",&x);
printf("%d\n",fib(x));
}
return 0;
}
//递推
#include <cstdio>
using namespace std;
const int mod = 1000;
const int MAXN = 1000000;
int n , f[MAXN + 1], x;
int main(){
scanf("%d",&n);
f[1] = f[2] = 1;
for(int i = 3; i <= MAXN; i++) f[i] = (f[i- 1] + f[i - 2]) % mod
//直接先预处理, 你要第几位丫?? 直接输出就是了
while(n--){
scanf("%d",&x);
printf("%d\n",f[x]);
}
return 0;
}