问题:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
解题思路及代码:
1. 正确解答:
//第一次的想法:max(全部只走一阶)-min(尽可能多的走两阶)+1就是所有的情况,但忽略了需要排列组合,造成错误。
//例如有如果11个台阶,只有一步走1个台阶,其他步都走2个台阶,那么这1个台阶是第几个台阶,这就涉及到了排列组合思想。太麻烦,放弃。。。
//发现规律:0(1)-1(1)-2(2)-3(3)-4(5)-5(8)...即F(n)=F(n-1)+F(n-2)。
int climbStairs(int n)
{
int former=1,latter=1; //这样选的原因是F(0)=F(1)=1(即迭代的两个初始值为1)。
int result;
if (n==0||n==1)
return 1;
for (int i=2; i<=n; i++) //fibnacci 大法(斐波那契数列C语言实现)
{
result=former+latter;
former=latter;
latter=result;
}
return result;
}
2. 我之前的想法:
#include<stdio.h>
#include<stdlib.h>
int climbStairs(int n);
void main()
{
int n=10;
int result;
result=climbStairs(n);
printf("如果楼梯有%d阶,每次只能爬1或2个台阶,那么有%d种方法爬到楼顶\n",n,result);
system("pause");
}
int climbStairs(int n)
{
/* 我的想法 */
//int max,min,result;
//min=n/2+n%2;
//max=n;
//result=max-min+1; //第一次的想法:max-min+1就是所有的情况,忽略了需要排列组合
//例如有如果11个台阶,只有一步走1个台阶,其他步都走2个台阶,那么这1个台阶是第几个台阶,这就涉及到了排列组合思想。
//return result;
//for(int i=0;i<max-min;i++) //考虑加入排列组合,好麻烦啊。。。放弃。。。
//{
// result+=
//}
/* 第一种解法 */
/*int former=1,latter=1; //这样选的原因是F(0)=F(1)=1(即迭代的两个初始值为1)。
//int result;
//if (n==0||n==1)
//return 1;
//for (int i=2; i<=n; i++)
//{
// result=former+latter;
//former=latter;
//latter=result;
//}
//return result;*/
/* 第二种解法 */
//dp[n]表示n道楼梯有几种爬的方法
//1 1 2 3 5 8...
//规律:F(n)=F(n-1)+F(n-2)
if(n==1)
return 1;
else if(n==2)
return 2;
else
{
int result[n+1];
result[0]=0;
result[1]=1;
result[2]=2;
for(int i=3;i<=n;i++)
{
result[i]=result[i-1]+result[i-2];//经过一步到第i道楼梯与经过两步到i道楼梯的方法数之和
}
return result[n];
}
}
知识点:
斐波那契(Fibnacci)数列的实现过程如下: