在c语言期末考试中,再次见到了“小明爬楼梯”问题,而第一次见到是在某次面试题中,由于当时还没有学到递归部分,因此就仅仅把代码看了一下,然而其中包含的思想却没有弄清楚,因此在考试时见到该题一头雾水,因此总结一下,以绝后患。
先上题:
可爱的小明特别喜欢爬楼梯,他有的时候一次爬一个台阶,有的时候一次爬两个台阶,有的时候一次爬三个台阶。如果这个楼梯有n个台阶,小明一共有多少种爬法呢?
该题为典型的递归
问题,解决的思想当然就要不按常理出牌:
假设当前共有36阶台阶,小明若想到达第36阶台阶,只能选择从第35阶再上1阶
,或从第34阶再上2阶
,或从第33阶再上3阶
,因此要想到达第36阶台阶,需要走的步数为到达之前3级台阶
需要的步数之和
,即f(n) = f(n-1) + f(n-2) + f(n-3)
.
示例代码:
#include <stdio.h>
int f(int n)
{
if(n == 1)
return 1;
if(n == 2)
return 2;
if(n == 3)
return 4;
return f(n-1) + f(n-2) + f(n-3);
}
int main (void)
{
int n;
printf("请输入台阶数:\n");
scanf("%d", &n);
printf("所需步数为:%d\n", f(n));
return 0;
}
到这里就结束了吗?没有!!!虽然用递归做很直观,但是递归却造成了运行速度相对而言是极慢的,因此再附上一份稍微复杂那么一丢丢但是运行速度快的代码:
#include<stdio.h>
int f(int n){
n++;
int i;
int table[n]; //存储台阶数为n时爬楼梯的类别数
for(i=0;i<n;i++)
table[i]=0;
table[1]=1;
table[2]=2;
table[3]=4;
for(i=4;i<n;i++){
table[i]=table[i-1]+table[i-2]+table[i-3];
}
return table[n-1];
}
int main(){
int n;
printf("请输入台阶数:\n");
scanf("%d", &n);
printf("%d\n",f(n));
return 0;
}
注:本题应考虑数字范围的问题,由于考试时只有几组简单的测试数据,因此仅仅使用了int
型数据,未使用long long
型数据。