感觉还会涉及大数运算问题,还好题干的规模比较小,有时间看心情再更新
(题目来自于wzu oj)
一开始还以为是题目问题,唉,梦回大一了属于是,少壮不努力...?
这么多年都白学了orz
1628 - 用递归法求台阶的走法
时间限制 : 2 秒
内存限制 : 128 MB
有n级台阶,可以一步上一级,也可以一步上两级。比如n=3,可以一级一级上,也可以先上一级再上两级,还可以先上两级再上一级,共有3种方式。对任意的n,问有多少种上n级台阶的方式?用递归函数实现。
输入
台阶的级数n。(1≤n≤45)
输出
上n级台阶的方式数。
题目要求时间2s内,下意识的写法
#include<stdio.h>
long step(long s){
if(s==1){
return 1;
}
if(s==2){
return 2;
}
return step(s-1)+step(s-2);
}
int main(){
long n;
scanf("%ld",&n);
printf("%ld",step(n));
}
40左右基本上就超时了
临界条件:n=1时为1,n=2时为2
递推关系:f(n)=f(n-1)+f(n-2)
这种写法在递归的过程中会不断的重复计算,递归过程有点像二叉树的样子,时间复杂度也保持在2^n,所以需要进行优化
比较直观的思路就是空间换时间,把重复计算的过程进行缓存,方法好想,不太好写
要点:需要声明缓存用的数组为static,只初始化一次
如果发现对应数组元素不为空,不继续下面递归过程,直接返回数组元素值
#include<stdio.h>
long step(long s){
if(s==1){
return 1;
}
if(s==2){
return 2;
}
static long temp[200];
if(temp[s]!=NULL){
return temp[s];
}
long r = step(s-1)+step(s-2);
temp[s] = r ;
return r;
}
int main(){
long n;
scanf("%ld",&n);
printf("%ld",step(n));
}
或者尾递归
#include<stdio.h>
long step(long s,long first,long second){
if(s==1){
return first;
}
if(s==2){
return second;
}
if(s==3){
return first+second;
}
return step(s-1,second,first+second);
}
int main(){
long n;
scanf("%ld",&n);
printf("%ld",step(n,1,2));
}