斐波那契数列及相关问题

来源:互联网 发布:数据库建模工具有哪些 编辑:程序博客网 时间:2024/06/05 02:19


斐波那契数列是这样一个数列0,1,1,2,3,5,8,13,21......可以很容易的看出斐波那契数列的规律,斐波那契数列的定义如下:

           0            n=0

f(n)=    1            n=1

       f(n-1)+f(n-2)    n>1

问题:实现一个函数,输入n,求斐波那契数列的第n项

解法一:递归

<span style="font-family:SimSun;font-size:14px;">long long Fibonacci(unsigned int n){    if(n <= 0)        return 0;    if(n == 1)        return 1;    return Fibonacci(n-1) + Fibonacci(n - 2);}</span>

此算法的效率是很低的,会有大量的重复操作,时间复杂度以n的指数方式增加。

调用次数:c(n)是求第n项调用的次数  c(0)=1;c(1)=1;c(n)=c(n-1)+c(n-2)+1;

解法二:循环

为了避免重复计算,可以把已经得到的数列中间项保存起来,直接使用,从上往下算,首先根据f(0),f(1)计算出f(2),再根据f(1),f(2)计算出f(3)...一次类推就可以计算出第n项了。

<span style="font-family:SimSun;font-size:14px;">long long Fibonacci(unsigned n){    int result[2] = {0 , 1};    if(n < 2)        return result[n];    long long fibMinusOne = 1;    long long fibMinusTwo = 0;    for(unsigned int i = 2 ; i <= n ; ++i)    {        fibN = fibMinusOne + fibMinusTwo;        fibMinusTwo = fibMinusOne;        fibMinusOne = fibN;    }    return fibN;}</span>

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

思路:首先考虑简单情况,如果只有1级,那么有1种跳法,如果有2级,有两种跳法,一次跳两级,另一种是分两次跳,每次跳一级。

把n级台阶时的跳法看成是n的函数,记为f(n)。当n>2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数

目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);另一种选择是第一次跳2级,此时跳法数目等于后面剩下n-2级台阶的跳法数

目,即为f(n-2)。因此,n级台阶的不同跳法的总数f(n)=f(n-1)+f(n-2)。可以看出这实际上就是斐波那契数列。解法有以上两种。


相关问题2:一只青蛙一次可以跳上1级台阶,也可以跳上2 级……它也可以跳上n 级,此时该青蛙跳上一个n级的台阶总共有多少种跳法?

用f(n)表示青蛙跳上n级台阶的跳法数,青蛙一次性跳上n级台阶的跳法数1(n级跳),设定f(0) = 1;

       当n = 1 时, 只有一种跳法,即1级跳:f(1) = 1;

       当n = 2 时, 有两种跳的方式,一次跳2级和两次跳每次跳一级:f(2) = f(1) + f(0) = 2;

       当n = 3 时,有三种跳的方式,第一次跳出一级后,后面还有f(3-1)中跳法; 第一次跳出二级后,后面还有f(3-2)中跳法;第一次跳出三级后,后面还有f(3-3)中跳法

        f(3) = f(2) + f(1)+f(0)=4;

       当n = n 时,共有n种跳的方式,第一次跳出一级后,后面还有f(n-1)中跳法; 第一次跳出二级后,后面还有f(n-2)中跳法..........................第一次跳出n级后, 后面有f(n-n)中跳法.

       f(n) = f(n-1)+f(n-2)+f(n-3)+..........+f(n-n)=f(0)+f(1)+f(2)+.......+f(n-1)

 又因为f(n-1)=f(0)+f(1)+f(2)+.......+f(n-2)

 两式相减得:f(n)-f(n-1)=f(n-1)         

 可以得到递归等式:  f(n) = 2*f(n-1)     n >= 2

  f(n)=2*2*2....*f(0)=2^n-1


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

思想:把长条n*2的覆盖问题分解,第一步,若竖着覆盖一个2*1的方块,那么剩下的为2*(n-1)块,否则,若横着覆盖,应用两块,覆盖一个2*2的块,剩下2*(n-2),这两种覆盖的方式都各有一种,这个问题等同于递归f(n)=f(n-1)+f(n-2)

<span style="font-family:SimSun;font-size:14px;">int main(){    long long n,k,i,j,t;    while(scanf("%lld",&n)!=EOF)    {        i=j=t=1;        for(k=0;k<n-1;k++)        {            t=i+j;j=i;i=t;        }        printf("%lld\n",t);    }    return 0;}</span>




0 0
原创粉丝点击