题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
初步思路
思考当有零次跳2级时,一次跳2级,到number/2(向下取整)次跳2级时,正好总数奇数级和偶数级是跳法的公式都是一样的,总跳法为C(n,0)+C(n-1,1)+...+C(n-number/2,number/2)
接着,按照这个思路编写了如下程序,一开始通过率一直小于50%,后来经过调试,发现是在算组合数的时候超过了int能表示的数的范围,进行了一定的优化防止溢出之后通过了。
优化的方法,在公式的基础上,每乘一个数,就除一个数,保证每次乘除之后的结果都是组合数,这样才不会出现小数。
附上int long等类型的范围:
unsigned int (unsigned long)
4字节8位可表达位数:2^32=42 9496 7296
范围:0 ~ 42 9496 7295 (42*10^8)
int (long)
4字节8位可表达位数:2^32=42 9496 7296
范围:-21 4748 3648 ~ 21 4748 3647 (21*10^8)
long long (__int64)
8字节8位可表达位数:2^64=1844 6744 0737 0960 0000
范围:-922 3372 0368 5477 5808 ~ 922 3372 0368 5477 5807 (922*10^16)
unsigned long (unsigned __int64)
8字节8位可表达位数:2^64=1844 6744 0737 0960 0000
范围:0 ~ 1844 6744 0737 0955 1615 (1844*10^16)
int method(int a,int b){
int temp = 1;
if(a>b/2)
a = b-a;
for(int i=0;i<a;++i){
temp *= b--;
temp /= i+1;
}
return temp;
}
int jumpFloor(int number) {
int sum=0;
for(int i=0;i<=number/2;++i){
sum+=method(i,number-i);
}
return sum;
}
实质
这道题的实质其实是考我们斐波那契数列,通过计算前几级的情况能发现是斐波那契数列,因此代码可以很简单。
int f(int a,int b,int n){
if(n==1)
return b;
return f(b,a+b,--n);
}
int jumpFloor(int number) {
return f(1,1,number);
}
变态跳台阶
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
解析
考察前几次的情况可以发现每次的跳法数都是前面多有的跳法数相加再加一,计算出结果为公比为2的等比数列,接下来就简单了。
int jumpFloorII(int number) {
int sum = 1;
for(int i=0;i<number-1;++i){
sum*=2;
}
return sum;
}