牛客网“剑指offer”栏中的一道题,原题描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
我的思路:
思路1(×):假定n个数字,有k个2,剩下都是1,其可能的排列方式为C_n_k(组合数),
根据规律,依次增加2的个数,组合数的和就是结果。O((n/2)*O(getC)).
由于n>20的时候数已经相当大了,故这里采用long long形式存储结果。
思路2(√):结果是斐波那契数列:1 2 3 5 8...,使用递归或非递归实现均可。
下面是两种思路的代码实现:
#include<iostream>
using namespace std;
int getC(int n,int k) {
if(n==0) {
return 0;
} else if(k==0) {
return 1;
}
int cut=n-k;
long long c=1,m=1;//分子、分母
for(int i=0; i<cut; i++) {
c*=n;
n--;
m*=(i+1);
}
long long res=c/m;
return res;
}
long long jumpFloor(int number) {
if(number<=0) {
return 0;
}
int max2=number/2;//最多几个2
int n;//总共几个数字
int k;//几个2
long long sum=0;
for(k=0; k<=max2; k++) {
n=number-k;
sum+=getC(n,k);
}
return sum;
}
int JumpFloor(int target) {
if (target <= 0) {
return -1;
} else if (target == 1) {
return 1;
} else if (target ==2) {
return 2;
} else {
return JumpFloor(target-1)+JumpFloor(target-2);
}
}
int main() {
//斐波那契
for(int i=1; i<=30; i++) {
cout<<JumpFloor(i)<<endl;
}
//组合数
for(int i=1; i<=30; i++) {
cout<<jumpFloor(i)<<endl;
}
return 0;
}
结果对比:
<左图:斐波那契法> <右图:组合数法>
很明显,两者从第22个结果开始不同了。Why?
且听下回分解...
别打我,我真的还没证出来...