题目地址
n为1时答案是1,从第一级踏上第一级,只能上一级或二级,不应该是0?
开始的时候用了dfs来做,但是我这样写的时间复杂度应该为O(2 ^ n),如果没估算错,毕竟新手,很可能是错的。
当n为40,2 ^ 40太大了,肯定超时,也不出所料,TL。
#include <cstdio>
#include <algorithm>
#include <ctime>
using namespace std;
int sum = 1;
int Count = 0;
int a[40 + 1];
/*
for(int i = 1; i <= 40; i++) {
a[i] = i;
}
*/
void dfs(int n) {
if(sum == n) {
Count++;
return ;
}
if(sum > n) {
return;
}
for(int i = 1; i <= 2; i++) {
sum += i;
dfs(n);
sum -= i;
}
}
int main(void) {
int N;
while(scanf("%d", &N) != EOF) {
int n;
for(int i = 1; i <= N; i++) {
scanf("%d", &n);
dfs(n);
printf("%d\n", Count);
Count = 0;
sum = 1;
}
}
printf("time:%.2f\n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}
解决方法是dp的思想,如果有n个阶梯,那么可以从第n - 1个阶梯走上去或者从第n - 2个阶梯走上去
从第n - 1个阶梯走上去只有一个那就是踏一级,也可以从第n - 2个阶梯走上去,走两个一级或者一个
二级,也许会有疑问,那不就是有两个可能了,走两个一级或者一个二级,可是别忘了,当走上一级
的时候,变成了第n - 1级了,那就变成了从第n - 1 级走上楼梯了,相当于第n - 1级走一级一级上去的话的可能状况都在从第n - 1走上楼梯。所以不用乘以2
所以状态转移方程为d[n] = d[n - 1] + d[n - 2],这也是递推的依据。
#include <cstdio>
#include <algorithm>
#include <ctime>
using namespace std;
int main(void) {
int N;
long long a[51];
a[1] = 1;
a[2] = 1;
a[3] = 2;
a[4] = 3;
for(int i = 5; i <= 50; i++) {
a[i] = a[i - 1] + a[i - 2];
}
while(scanf("%d", &N) != EOF) {
int n;
for(int i = 1; i <= N; i++) {
scanf("%d", &n);
printf("%I64d\n", a[n]);
}
}
printf("time:%.2f\n", (double)clock() / CLOCKS_PER_SEC);
return 0;
}