斐波那契数列的四种解法

简介: 斐波那契数列的四种解法

题目描述


斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列: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*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从 1963 年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。


解法一:通项公式(O(1))

7354cdbd32d34c80b16a2cae930fa398.png

代码表示:

int ferbo(int n){
  return (sqrt(5)/5)*(pow((1+sqrt(5))/2,n)-pow((1-sqrt(5))/2,n));
}


解法二:递归求解(O(1.618^n))

#include<iostream>
using namespace std;
int fac(int x){
  if(x==1 || x==2){
    return 1;
  }
  if(x>2){
    return fac(x-1)+fac(x-2);
  }
  return 0;
}
int main()
{
  for(int i = 1; i<=20;i++){
    cout<<fac(i)<<" ";
  }
  cout<<endl;
  return 0;
}
//1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

解法三:动态规划(O(n))

#include<iostream>
using namespace std;
int fac[20];
int main()
{
  fac[1]=fac[2]=1;
  for(int i = 3;i<=20;i++){//此处使用变量a,b,c也可。 
    fac[i] = fac[i-1]+fac[i-2];
  }
  for(int i = 1;i <=20;i++){
    cout<<fac[i]<<" ";
  }
  cout<<endl;
  return 0; 
}
//1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

解法四:矩阵快速幂(O(logn))

矩阵公式
 F(n+1)=1*F(n)+1*F(n-1)
 F(n)=1*F(n)+0*F(n-1)
 F(n)=1*F(n-1)+1*F(n-2)
 F(n-1)=1*F(n-1)+0*F(n-2)

推导:


812569667dcf41b89f9e6f12340e28da.png


结论:只需要求出

9045c5a301b3485abe9fba84289434d6.png

,输出a[0][1] 或a[1] [0]都是F(n)的解.

快速幂

mod c只是为了防止数过大,不利于计算. 当数很小 时,加不加没啥区别.

b204f785f20041429c26e15b9734522d.png

例如求a^n, (a=2)初始时,ans=1;

  • 如果n=4,则计算步骤如下:
a=a*a=a^2   n=n/2=2
a=a*a=a^2 * a^2 = a^4  n=n/2=1
ans=ans*a=a^4
  • 如果n=5,则计算步骤如下
因为n为奇数==>ans=ans*a    a=a*a=a^2   n=n/2=2
a=a*a=a^2 * a^2 = a^4  n=n/2=1
ans=ans^a=a^5
  • 如果n=9,则计算步骤如下
因为n为奇数==>ans=ans*a    a=a*a=a^2   n=n/2=4
a=a*a=a^4   n=n/2=2
a=a*a=a^8   n=n/2=1
ans=ans^a=a^9

这样就把8次运算减少到了四次.而且也放置了数值过大的问题.

总结:当n为奇数时,ans=ans*a,这样相等于n-1变成了偶数.

快速幂代码

#include<iostream>
using namespace std;
int main() {
  int n,p,ans=1,a=2;
  cin>>n>>p;
  while(n) {
    if(n&1) {
      ans = ans * a %p;
    }
    a *= a % p;
    n/=2;
  }
  cout<<ans<<endl;
  return 0;
}
//16 1000000
//65536

矩阵快速幂

9e856cdb8fc34724a63b6f5b38cc1694.png

f3a2f071a3d740e7ab059b9e039d46d3.png


矩阵乘法:

原理:矩阵相乘最重要的方法是一般矩阵乘积。它只有在第一个矩阵的栏数(column)和第二个矩阵的列数(row)相同时才有定义。一般单指矩阵乘积时,指的便是一般矩阵乘积。若A为m×n矩阵,B为n×p矩阵,则他们的乘积AB会是一个m×p矩阵。其乘积矩阵的元素如下面式子得出:

7d636d8ab1f2407a88afabe5afb4a36f.png


实现代码:

struct mat{
    int n, m;
    double data[MAXN][MAXN];
};
int mul(mat& c, const mat& a, const mat& b){
    int i, j, k;
    if (a.m != b.n)
        return 0;
    c.n = a.n;
    c.m = b.m;
    for (i = 0; i < c.n; i++)
        for (j = 0; j < c.m; j++)
            for (c.data[i][j] = k = 0; k < a.m; k++)
                c.data[i][j] += a.data[i][k] * b.data[k][j];
    return 1;
}

例题:POJ3070

以上内容参考自 陈小玉老师的数据结构与算法 365天特训营

相关文章
|
2月前
斐波那契数列
【10月更文挑战第19天】斐波那契数列。
36 3
|
3月前
|
Java
01_斐波那契数列
01_斐波那契数列
|
6月前
|
算法
【超直白】算法:斐波那契数列
【超直白】算法:斐波那契数列
【超直白】算法:斐波那契数列
|
6月前
|
存储 算法
精益求精——斐波那契数列的logn解法
精益求精——斐波那契数列的logn解法
85 0
|
7月前
|
算法 索引
Leetcode算法系列| 1. 两数之和(四种解法)
Leetcode算法系列| 1. 两数之和(四种解法)
(1188:1201:)斐波那契数列
(1188:1201:)斐波那契数列
155 0
|
机器学习/深度学习 开发工具
斐波那契数列的四种实现
在编程教程中提到斐波那契数列,通常都是用来讲解递归函数。当一个关于 N 的问题可以转换为关于 N - k 的同样问题时,它就可以尝试用递归的思路来解决。
斐波那契数列问题
斐波那契数列问题
102 0
|
前端开发 程序员 测试技术
斐波那契数列的多种解法
斐波那契数列的多种解法
斐波那契数列的多种解法
|
算法
30.斐波那契数列
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。 n<=39
76 0
30.斐波那契数列