http://raychase.iteye.com/blog/1337359
题目:一只青蛙一次可以跳1级台阶,也可以跳2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
这道题还被ITEye放在了博文视点杯有奖答题活动里面。
我提供三种解法。
1、递归求解:
青蛙每跳一次前,有这样三种情况:
(1)只剩1级或0级台阶了,只能跳一步或者无法再跳了,那么这条路也走到了终点,走法的种类数可以加1;
(2)可以走2级台阶;
(3)可以走1级台阶。
于是递归方法求解:
2、概率论思路求解:
首先把问题抽象成简单的数学模型,设2步台阶跳了x次,1步台阶跳了y次,那么:
2x + y = n
于是,当 x = i ,可知 x >= 0 ,且 x < n/2 (向下取整),设某时刻的 x = i ,那么有 y = n - 2 * x ,于是,总共需要走 z = i + n - 2 * x 步。
这时,问题即转化为:
z步骤中,有x个两步,y个一步,相当于z个空当,由x、y去填充,那么不同填充方法的数目符合概率公式:
C(x,z) = z! / ((z-x)!x!)
即从排列z中取其中x个数的种类,x内部无序:
3、数学归纳法求解:
如果n=1,总步数f(n)=1;如果n=2,总步数f(n)=2。
另一方面,当n>=3,当前还剩的步数f(n),如果接下去跳一步,那么还剩下的步数是f(n-1);如果接下去跳两步,那么还剩下的步数是f(n-2),故:f(n)=f(n-1)+f(n-2)。
现设s3=f(n),s2=f(n-2),s1=f(n-1),从时间、空间复杂度来说,这也是最简单的一种方法:
聪明的你,还有什么办法?
欢迎和我讨论。 :)
suirosu找到一种:
由两步台阶的多少可以推论出:
两步台阶:
0 1 2 3
单步台阶:
n n-1*2 n-2*2 n-2*3 ...................
总的步数:
n 1+(n-1*2) 2+(n-2*2) 3+(n-2*3)...........
总步数由单双步组成,求单步或双步的分布,再总相加就可求出总的步数。求一种步的分布可表示如下:
C(n,0) C(1+(n-1*2),1) C(2+(n-2*2),2) C(3+(n-2*3),3).......
写成程序可表示如下:
#include <iostream>
#include <deque>
using namespace std;
unsigned int C(int n, int m)
{
deque<int> nset;
for (int i = 2; i <= m; i++)nset.push_back(i);
unsigned int mulrl1 = 1;
for (int ni = n; ni > n-m; ni--)
{
int nitemp = ni;
for (int j = nset.size() - 1; j >= 0 && nset.size();j--)
{
if (nitemp%nset[j] == 0)
{
nitemp = nitemp / nset[j];
nset.erase(nset.begin() + j);
}
}
mulrl1 = mulrl1*nitemp;
}
for (auto nsetit = nset.begin(); nsetit != nset.end(); nsetit++)
{
mulrl1 = mulrl1 / *nsetit;
}
return mulrl1;
}
int main(int argc, char *argv[])
{
int nStep = 0;
cout << "输入要跳的台阶数: ";
cin >> nStep;
int Total = 0;
for (int i = 0; i < nStep; i++)
{
Total += C(nStep - i, i);;
}
cout << "共有:" << Total << "种跳法。" << endl;
}