【九度oj】1387 1388 1389 1390 斐波那契数列

题目1387  斐波拉契数列

原题链接:http://ac.jobdu.com/problem.php?pid=1387

题目描述:实现最基本的斐波那契数列。

注意:

  1. 首先想到的就是递归,但是递归是超时的。此时需要将递归写成循环的形式。
  2. 斐波那契数列的第70个,已经是很大很大的数据了,long int 根本不够,应该使用 long long 类型。
  3. 递归的题目,一定将结果都存在数组中,根据下标输出。千万不要根据一个输入再去计算。
#include<stdio.h>
#include<stdlib.h>
 
int main(){
    int n;
    long long ans[71];
    ans[0] = 0;
    ans[1] = 1;
    for(int i=2; i<71; i++)
    {
        ans[i] = ans[i-1] + ans[i-2];
    }
    while(scanf("%d", &n) != EOF)
    {
        printf("%lld\n", ans[n]);
    }
    return 0;
}

 

题目1388  跳台阶

原题链接:http://ac.jobdu.com/problem.php?pid=1388

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

算法描述:反向思维,思考青蛙跳的最后一步。

  1. 青蛙最后跳一步,即 n = (n-1) + 1,则等于青蛙跳 (n-1) 级台阶的跳法。
  2. 青蛙最后跳两步,即 n = (n-2) + 2,则等于青蛙跳 (n-2) 级台阶的跳法。

最后得出,满足 f(n) = f(n-1) + f(n-2) 的斐波那契表达式。

此题还有变种,即一只青蛙一次可以跳上1级台阶,也可以跳上2级,还可以跳上3级。那么就满足 f(n) = f(n-1) + f(n-2) + f(n-3)。以此类推。

 

题目1389  变态跳台阶

原题链接:http://ac.jobdu.com/problem.php?pid=1389

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

算法描述:

好吧,其实我是找规律做出来的……我非常逗比地没有想到使用斐波那契思想。而是发现了 f(n) = 2^(n-1) 的规律,这也是一种解题思路:数学归纳法。

正确思维应该是,思考青蛙跳的最后一步。

  1. 青蛙最后跳一步,即 n = (n-1) + 1,则等于青蛙跳 (n-1) 级台阶的跳法。
  2. 青蛙最后跳两步,即 n = (n-2) + 2,则等于青蛙跳 (n-2) 级台阶的跳法。
  3. ……
  4. 青蛙最后跳 (n - 1)步,即 n = 1 + (n-1),则等于青蛙跳 1 级台阶的跳法。
  5. 青蛙直接跳 n 步上台阶。

最后得出,满足 f(n) = f(n-1) + f(n-2) + … + f(1) + 1 的斐波那契表达式。

 

题目1390  矩形覆盖

原题链接:http://ac.jobdu.com/problem.php?pid=1390

题目描述:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

算法描述:

不要被”输出“中的 n 为偶数迷惑。就一个一个 n 来。

把长条n*2的覆盖问题分解,思考最后一步加上的一条边:若竖着覆盖一个 2*1 的方块,那么剩下的为 2*(n-1) 块;若横着覆盖,应使用 2 块,覆盖一个 2*2 的块,剩下 2*(n-2),这两种覆盖的方式都各有一种。

最后得出,满足 f(n) = f(n-1) + f(n-2) 的斐波那契表达式。

 

总结

斐波那契数列的做法,都是需要从最后一步开始思考:最后一步如果这么做,能不能使用(n - subn) 时候的结论?使用时有没有变种,需不需要乘以系数?

通式:f(n) = f(n-1)*coeff(1) + f(n-2)*coeff(2) + … + f(1)*coeff(n-1)

最后需要注意的是避免递归而使用循环。循环时使用数组保存每个结果,而不是一个输入之后再计算。

你可能感兴趣的:(递归,斐波那契,九度,跳台阶,矩形覆盖)