70. Climbing Stairs
原题链接
You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
原题大意:
- 给一个台阶数为n的楼梯,一次能跨一个或者两个台阶,写出一个函数算出有几种方式登顶
Note:
- Given n will be a positive integer.(n是正整数)
思路:
- 看到题目,首先想到了分类,每一类中(一个台阶一步)和(两个台阶一步)的数量是固定的
- 各个类之间,一个台阶一步的数量减2,两个台阶一步的数量+1
- 单个类,找出跨一步和两步的数量one, two,用排列组合的方法,总共one+one个空,
- 随机插入one或者two,即可得到方法数,公式由下图给出(不会电脑作图,只能手机拍摄,见谅)
代码如下:
#include <iostream>
using namespace std;
class Solution {
public:
int climbStairs(int n) {
if(n<=0) return 0;
if(n==1) return 1;
double res=0;//记录爬楼梯方式的数量 必须用double 否则会出现误差
//one一步一个台阶的次数 two一步两个台阶的次数
for(int one=n,two=0; (one>=0)&&(two<=n/2); one-=2,two++){
if(one==0 || two==0)
res += 1;
else{
double temp = factorial(one+two)/(factorial(one)*factorial(two)); //必须用double 否则会出现误差
res += temp;
}
}
return res;
}
double factorial(int n){
if(n==0) return 1;//0的阶乘是0
double res = 1;
for(int i=2; i<=n; i++)
res*=i;
return res;
}
};
int main()
{
Solution s;
int a = 0;
cin >> a;
cout << s.climbStairs1(a) << endl;
return 0;
}
遇到的困难:
- 由于用到了排列组合,我写了一个求阶乘的函数,但是阶乘很容易求得的结果超出int范围,总会出现误差,提示除数为0等一系列问题,我就把所有的int换成了double,执行AC了,有点侥幸的感觉。。。。。
探寻新方法:
- 后来我去Disscuss看大家的思路,果然天外有人,总有新世界的大门打开
- one_step_before表示最后一步登顶跨出一个台阶的方法数
- two_steps_before表示最后一步登顶跨出两个台阶的方法数
- 总方法数all_ways = one_step_before + two_steps_before
- 用类似于fibonacci的方法求解
- 附上链接
代码如下:
int climbStairs(int n) {
if(n<=0) return 0;
if(n==1) return 1;
if(n==2) return 2;
//one_step_before表示最后一步登顶跨出一个台阶的方法数
//two_steps_before表示最后一步登顶跨出两个台阶的方法数
//总方法数all_ways = one_step_before + two_steps_before
//n=3时 对one_step_before,two_steps_before初始化
int one_step_before = 2;
int two_steps_before = 1;
int all_ways = 0;//记录爬楼梯方式的总数
for(int i=2; i<n; i++){
all_ways = one_step_before + two_steps_before;
two_steps_before = one_step_before;
one_step_before = all_ways;
}
return all_ways;
}