九度OJ-题目1388:跳台阶

题目链接地址:

九度OJ-题目1388:跳台阶


题目描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

输入:
输入可能包含多个测试样例,对于每个测试案例,
输入包括一个整数n(1<=n<=70)。

输出:
对应每个测试案例,
输出该青蛙跳上一个n级的台阶总共有多少种跳法。

样例输入:
5

样例输出:
8


解题思路:

假设青蛙要跳上n(n >= 2)级台阶,用f(n)来表示青蛙跳上一个n级台阶的跳法数目。因为青蛙每次可以选择跳上1级台阶或者2级台阶,所有可以分以下两种情况进行讨论:
(1) 如果青蛙选择跳上1级台阶,那么就还剩下n - 1级台阶,而跳上n – 1级台阶的跳法数目是f(n - 1);
(2) 如果青蛙选择跳上2级台阶,那么就还剩下n - 2级台阶,而跳上n – 2级台阶的跳法数目是f(n - 2)。
从上面的分析过程可以看出跳上一个n级台阶的问题可以分解为跳上一个n – 1级台阶和跳上一个n – 2级台阶这两个子问题,而分解后得到的问题在本质上并没有发生改变,只是问题的规模从n减少到了n - 1和n – 2,这感觉就是递归了。举个栗子,当n = 5时,可以看到问题的分解过程如图1所示:

九度OJ-题目1388:跳台阶_第1张图片

图1 跳上一个5级台阶的问题分解过程

从图1可以看出,跳上一个n级台阶的问题最终都会被分解成跳上一个1级和跳上一个0级台阶的子问题,如果知道跳上1级台阶和跳上0级台阶的跳法数目,就能推算出跳上一个n级台阶的跳法数目。很明显跳上一个1级台阶的跳法只有1种,所以f(1) = 1。那么该如何计算跳上一个0级台阶的跳法数目呢?我是这样理解的:当青蛙要跳上一个只有1级的台阶时,它只有跳1级台阶这一种选择,当青蛙跳上一级台阶以后,剩余的台阶数目就变成了0,所以可以得出f(1) = f(0)这个结论。为了验证f(0) = 1这个结论是否正确,当n = 2时,可以由公式f(n) = f(n - 1) + f(n - 2)得出f(2) = f(1) + f(0) = 2,而青蛙跳上一个2级的台阶有2种跳法,所以可以证明f(0) = 1这个结论是对的。

综上所示,求青蛙跳上一个n级台阶的跳法数目的公式如下:


细心的童鞋可能已经发现这就是经典的斐波那契数列,因为递归方法的效率太低了,所以一般有迭代法来求斐波那契数列。当遇到比较复杂的问题时,我一般会想办法用递归的思想将原问题转化为本质不变但规模更小的子问题,然后再用迭代法由已知子问题的解逐步推算出原问题的解。关于递归和迭代,感兴趣的童鞋可以看看这篇博客:递归与迭代

AC代码如下:

#include
 
/**
* 计算n(1<=n<=70)级台阶所对应的跳法数目
* @param jumpMethods  用于保存跳台阶的跳法数目
* @return void
*/
void getNumberOfJumpStepMethods(long long * jumpMethods)
{
  int i;
  jumpMethods[0] = 1;
  jumpMethods[1] = 1;
  for(i = 2;i <= 70;i++)
  {
     jumpMethods[i] = jumpMethods[i - 2] + jumpMethods[i - 1];
  }
}
 
int main()
{
    int n;
    long long jumpMethods[71];            // 记录跳台阶的跳法数目
    getNumberOfJumpStepMethods(jumpMethods);
    while(EOF != scanf("%d",&n))
    {
        printf("%lld\n",jumpMethods[n]);
    }
    return 0;
}
 
/**************************************************************
    Problem: 1388
    User: blueshell
    Language: C
    Result: Accepted
    Time:0 ms
    Memory:912 kb
****************************************************************/


你可能感兴趣的:(九度OJ-剑指Offer)