斐波那契数列

斐波那契数列

斐波那契数列问题

描述:斐波那契数列(Fibonacci sequence),指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……
斐波那契数列以如下被以递推的方法定义:
F(0)=0
F(1)=1
F(n)=F(n-1)+F(n-2)(n ≥ 2,n ∈ N*)

递归算法

#include <iostream>
using namespace std;

int f(int n)
{
	if(n==0) return 0;
	if(n==1) return 1;
	return f(n-1)+f(n-2);
} 
int main()
{
    cout<<f(5)<<endl;
    return 0;
}

非递归算法

1.使用数组储存前一项

#include <iostream>
using namespace std;

int main()
{
    int num[100];
    num[0]=0;
    num[1]=1;
    int n=5;
    for(int i=2;i<=n;i++){
    	num[i]=num[i-1]+num[i-2];//数组储存
	}
	cout<<num[n]<<endl;
    return 0;
}

2.使用队列

#include <iostream>
#include <queue>
using namespace std;

int main()
{
    int n=5;//要求的第n项
    queue <int> Q;//创建队列
    Q.push(0);
    Q.push(1);
    for(int i=2;i<=n;i++){
        int a=Q.front();Q.pop();
        int b=Q.front();//Q.pop();
        Q.push(a+b);
    }
    
    Q.pop();//结束之后队列里还剩下两个元素,要出队一个,剩下的才是所求
    cout<<Q.front()<<endl;
    return 0;
}

迭代算法

a = a + b;
b = a - b ;
完成一次迭代
迭代过程

#include <iostream>
using namespace std;

int fib(int n) {
    if (n == 0 || n == 1)
        return n;

    int a = 1, b = 0;
    for (int i = 1; i < n; i++) {
        a = a + b;
        b = a - b;
    }
    return a;
}
int main()
{
    cout<<fib(5)<<endl;
    return 0;
}

效率分析

递归算法在一般情况下会超时,不太适用于网站提交,将其转换为非递归算法

问题展开

爬楼梯问题

小明爬楼梯,他一次可以爬1阶楼梯或者2阶楼梯。
爬1阶楼梯,共有1种方法;
爬2阶楼梯,共有2种方法;
爬3阶楼梯,共有3种方法;
爬4阶楼梯,共有5种方法…
如果爬n阶楼梯,共有多少种方法?

思路

如果要爬到n阶,这个人必须先爬到n-1阶或者n-2阶。如果爬到n-1阶,那么只需要一次爬1阶就可以到达n阶;如果爬到n-2阶,那么只需要一次爬2阶就可以到达n阶。
所以,爬到n阶的方法=爬到n-1阶的方法+爬到n-2阶的方法。
所以这是一个斐波那契数列,F(n)=F(n-1)+F(n-2)。

兔子繁殖问题

有1只兔子,从出生后第3个月起每个月都生1只兔子,小兔子长到第3个月后每个月又生1只兔子,假如兔子都不死,问每个月的兔子总数为多少?
第1个月,有1只兔子;第2个月,有1只兔子;第3个月,有2只兔子;第4个月,有3只兔子;第5个月,有5只兔子…

思路

要求第n个月的兔子,首先第n-1个月的兔子在第n个月全部活着,即有F(n-2)只兔子。而对于第n-2个月的兔子,一部分是最新出生的兔子(第n个月就是他们的第3个月),一部分是老兔子。所以第n-2个月的所有兔子都在第n个月生1只兔子,即有F(n-2)只兔子。最终可以得到F(n)=F(n-1)+F(n-2)。

代码

#include <iostream>
using namespace std;

int main()
{
    int n;
    int f[100];
    f[0]=f[1]=1;
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        f[i]=f[i-2]+f[i-1];
    }
    cout<<f[n]<<endl;

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值