跳台阶算法
计科小马在地面,面前有一楼梯共M级。若每次只能向上跳1级,4级或7级,那么要走上第M级,共有多少种走法?
输入数据每行包含一个整数M(1<=M<=10000),表示楼梯的级数。以0表示结束。
对于每个测试实例,请输出不同走法的数量。由于数值比较大输出对20170920的余数。
//计科小马在地面,面前有一楼梯共M级。若每次只能向上跳1级,4级或7级,那么要走上第M级,共有多少种走法?
//输入数据每行包含一个整数M(1<=M<=10000),表示楼梯的级数。以0表示结束。
//对于每个测试实例,请输出不同走法的数量。由于数值比较大输出对20170920的余数。
/*
f(n) = f(n-1) + f(n-4) + f(n-7)
f(0) = 1
f(1) = f(1-1)
*/
#include <stdio.h>
//计科小马在地面,面前有一楼梯共M级。若每次只能向上跳1级,4级或7级,那么要走上第M级,共有多少种走法?
//输入数据每行包含一个整数M(1<=M<=10000),表示楼梯的级数。以0表示结束。
//对于每个测试实例,请输出不同走法的数量。由于数值比较大输出对20170920的余数。
//为什么要输出对20170920的余数
int f(int n ) {
if (n==0)return 1;
int sum = 0 ;
if (n>=1) sum += f(n-1);
if (n>=3) sum += f(n-4);
if (n>=7) sum += f(n-7);
return sum%20170920;
}
int main(int argc, char** argv) {
printf("%d",f(20)); //715
return 0;
}
有个问题:为什么要输出对20170920的余数
查看f(3)被调用了多少次,下面的f函数代码中写的是if(n==3)所以是判断f(3)
可以在运行结果看到输入20后(20个级台阶)输出了有715种方法,
然后输入0结束,之后再输出了f(3)被调用的次数,当我们输入的次数开始超过50次之后就会发现程序响应的时间越来越久了。
备忘录方法记录值
使用备忘录方法来记录这个数有没有被计算过(数组)
然后再f函数里面先判断数组里面的元素是否大于0,大于0直接返回元素,否则就计算,然后将结果赋值给数组元素并返回
int Memo[20000];
int f(int n) {
if (Memo[n]>0) return Memo[n];
if (n==0)return 1;
int sum = 0 ;
if (n>=1) sum += f(n-1);
if (n>=3) sum += f(n-4);
if (n>=7) sum += f(n-7);
Memo[n] = sum%20170920;
return Memo[n];
}
int main(int argc, char** argv) {
int i ;
while (1){
scanf("%d",&i);
for(int a=1;a<=i;a++) Memo[a]=0;//初始化Memo
if (i==0) break;
printf("%d\n",f(i));
}
// printf("%d",f(20)); //715
return 0;
}
报错显示:
21 3 C:\Users\user\Desktop\main.c [Error] 'for' loop initial declarations are only allowed in C99 or C11 mode
为什么错了?
因为C语言在devc++中好像是不能直接在for循环中定义的,要先在for循环前面定义,也就是:
int a ;
for (a=0;a<10;a++)
printf("%d",a);
#include <stdio.h>
int Memo[20000];
int main(void ) {
int i ;
while(1){
scanf("%d",&i);
if (i==0) break;
Memo[0]=1;
int a;
for (a=1;a<=i;a++){
int sum = 0;
if(a>=1) sum+=Memo[a-1];
if(a>=4) sum+=Memo[a-4];
if(a>=7) sum+=Memo[a-7];
Memo[a] = sum%20170920;
}
printf("%d\n",Memo[i]);
}
return 0;
}