0 递归

斐波那契数列定义:

$F(n)=\left\{\begin{matrix}
0, & n=0\\
1, & n=1\\
F(n-1)+F(n-2), & n>1
\end{matrix}\right.$

递归解法最直观,但是复杂度也最高:$O(2^n)$

 int Fibonacci(int n)
{
if (n <= ) //细节可以处理非法输入
return ;
else if ( == n)
return ;
return Fibonacci(n - ) + Fibonacci(n - );
}

为了避免重复计算,可以将每一步计算得到的$F(i)$存起来,这样的话时间复杂度降为$O(n)$,但空间复杂度升为$O(n)$。

1 通项

求解通项的方法有好几种,下面展示一种用线性代数求解的方法:

斐波那契数列的递推公式是二阶差分方程,先用一点小技巧将其化为一阶:

$$
\begin{cases}
F_{k+2}=F_{k+1}+F_{k}& \text{}\\
F_{k+1}=F_{k+1}& \text{}\\
\end{cases}$$

我们令$u_k=\begin{bmatrix}
F_{k+1}\\
F_{k}\\
\end{bmatrix}$,那么$u_{k+1}=\begin{bmatrix}
F_{k+2}\\
F_{k+1}\\
\end{bmatrix}=\begin{bmatrix}
1 & 1\\
1 & 0\\
\end{bmatrix}u_k$。

矩阵$A=\begin{bmatrix}
1 & 1\\
1 & 0\\
\end{bmatrix}$,令$det(A-\lambda I)=\lambda^2-\lambda-1=0$,求得$\lambda=\frac{1\pm \sqrt5}{2}$,对应于两个特征值的特征向量为$x_1=\begin{bmatrix}
\lambda_1\\
1\\
\end{bmatrix},x_2=\begin{bmatrix}
\lambda_2\\
1\\
\end{bmatrix}$。
求得特征值和特征向量后,我们将$u_0=\begin{bmatrix}
F_1\\
F_0\\
\end{bmatrix}=\begin{bmatrix}
1\\
0\\
\end{bmatrix}=c_1x_1+c_2x_2$,解得$c_1=-\frac{1}{\sqrt5}, c_2=\frac{1}{\sqrt5}$

$u_k=S\Lambda^{k}c=\begin{bmatrix}
c_1\lambda_1^{k+1}+c_2\lambda_2^{k+1}\\
c_1\lambda_1^{k}+c_2\lambda_2^{k}\\
\end{bmatrix}$

所以通项公式可以表示为$F(n)=C_1\lambda_1^n+C_2\lambda_2^n$。

故斐波那契数列的通项公式为:
$F(n)=\frac{1}{\sqrt5}[(\frac{1+\sqrt5}{2})^n-(\frac{1-\sqrt5}{2})^n]$

用公式求解的复杂度为$O(1)$,但是由于无理数在计算机中的存储不是精确的,所以结果的精度很难保证。

2 分治

通过矩阵形式的递推:

$$\begin{bmatrix}
F(n)\\
F(n-1)
\end{bmatrix}=\begin{bmatrix}
1 & 1\\
1 & 0
\end{bmatrix}\begin{bmatrix}
F(n-1)\\
F(n-2)
\end{bmatrix}$$

不断向下递推,可以得到:

$$\begin{bmatrix}
F(n)\\
F(n-1)
\end{bmatrix}={\begin{bmatrix}
1 & 1\\
1 & 0
\end{bmatrix}}^{n-1}\begin{bmatrix}
F(1)\\
F(0)
\end{bmatrix}$$

接下来就是求解矩阵的高次方,通过快速幂(https://baike.baidu.com/item/快速幂/5500243?fr=aladdin)可以在$O(logn)$时间内进行计算:
整数的快速幂代码:

 int QuickPow(int a,int n)
{
int ans = ;
while (n)
{
if (n & )
ans *= a;
a *= a;
n >>= ;
} return ans;
}
 // 递归版本
int raise(int base, int exp) {
if (exp == )
return ;
int half = raise(base, exp / );
if (exp % )
return base * half * half;
else
return half * half;
}

将传入的参数改为矩阵,乘法改为矩阵乘法,就可以得到矩阵快速幂:

以二阶矩阵为例,求解斐波那契数列:

 #define _CRT_SECURE_NO_WARNINGS

 #include <iostream>

 using namespace std;

 struct Matrix {
int a[][];
}base,ans; Matrix multi(Matrix a, Matrix b)
{
Matrix res;
for (int i = ; i < ; i++) //第i行
{
for (int j = ; j < ; j++) //第j列
{
res.a[i][j] = ;
for (int k = ; k < ; k++)
res.a[i][j] += a.a[i][k] * b.a[k][j];
}
} return res;
} Matrix QuickPow(int n)
{
base.a[][] = base.a[][] = base.a[][] = ;
base.a[][] = ; //初始化矩阵 //结果矩阵初始化为单位阵
ans.a[][] = ans.a[][] = ;
ans.a[][] = ans.a[][] = ; while (n)
{
if (n & )
{
ans = multi(ans, base);
}
base = multi(base, base);
n >>= ;
} return ans;
} int main()
{
int n;
cin >> n; QuickPow(n);
cout << ans.a[][] << endl; return ;
}

3 动态规划

 int Fibonacci(int n) {
int a = , b = ;
int ans = ;
for(int i = ;i < n;++i) {
ans = a + b;
a = b;
b = ans;
}
return ans;
}

参考:https://www.zhihu.com/question/28062458/answer/39763094

Fibonacci Sequence的更多相关文章

  1. 【每天一题ACM】 斐波那契数列(Fibonacci sequence)的实现

    最近因为一些原因需要接触一些ACM的东西,想想写个blog当作笔记吧!同时也给有需要的人一些参考 话不多说,关于斐波那契数列(Fibonacci sequence)不了解的同学可以看看百度百科之类的, ...

  2. ***1133. Fibonacci Sequence(斐波那契数列,二分,数论)

    1133. Fibonacci Sequence Time limit: 1.0 secondMemory limit: 64 MB is an infinite sequence of intege ...

  3. python实现斐波那契数列(Fibonacci sequence)

    使用Python实现斐波那契数列(Fibonacci sequence) 斐波那契数列形如 1,1,2,3,5,8,13,等等.也就是说,下一个值是序列中前两个值之和.写一个函数,给定N,返回第N个斐 ...

  4. 用递归方法计算斐波那契数列(Recursion Fibonacci Sequence Python)

    先科普一下什么叫斐波那契数列,以下内容摘自百度百科: 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因意大利数学家列昂纳多·斐波那契(Leonardoda Fibonacci ...

  5. [Algorithm] Fibonacci Sequence - Anatomy of recursion and space complexity analysis

    For Fibonacci Sequence, the space complexity should be the O(logN), which is the height of tree. Che ...

  6. SQL Server ->> 斐波那契数列(Fibonacci sequence)

    斐波那契数列(Fibonacci sequence)的T-SQL实现 ;WITH T AS ( AS BIGINT) AS curr, CAST(NULL AS BIGINT) AS prv UNIO ...

  7. python3 求斐波那契数列(Fibonacci sequence)

    输出斐波那契数列的前多少个数. 利用函数 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan # ----斐波那契数列( ...

  8. LeetCode 842. Split Array into Fibonacci Sequence

    原题链接在这里:https://leetcode.com/problems/split-array-into-fibonacci-sequence/ 题目: Given a string S of d ...

  9. Computational Complexity of Fibonacci Sequence / 斐波那契数列的时空复杂度

    Fibonacci Sequence 维基百科 \(F(n) = F(n-1)+F(n-2)\),其中 \(F(0)=0, F(1)=1\),即该数列由 0 和 1 开始,之后的数字由相邻的前两项相加 ...

  10. fibonacci number & fibonacci sequence

    fibonacci number & fibonacci sequence https://www.mathsisfun.com/numbers/fibonacci-sequence.html ...

随机推荐

  1. 本地代码上传到git仓库(github)

    准备:拥有自己的github账号:电脑上安装了git; 1.进入github,进入仓库点击NEW(新建仓库) 2.新建仓库 Repository name :仓库名称: Description (op ...

  2. MTK Android 耳机线控的实现方法

    android 耳机线控的实现方法 keycodeonkeydownkeyevent 耳机线控的功能 耳机线控是一种很好用,并且能提升用户体验的功能.可以用来实现一些常用和基本的功能.比如:实现音乐播 ...

  3. C++ memset函数用法

    #include<stdio.h>#include<string.h>int main(){ char buffer[] = "I love you!"; ...

  4. Mac系统中安装virtualenv虚拟环境

    总体来说有三个步骤. 1.创建工作目录. python3 -m venv lanyue_env 注意: 2.安装virtualenv. pip3 install --user virtualenv 2 ...

  5. windows powershell校验下载的文件MD5和SHA1值

    Windows自带MD5 SHA1 SHA256命令行工具 certutil -hashfile <文件名> <hash类型> 打开windows powershell,进入到 ...

  6. [总结]Floyd算法及其应用

    目录 一.Floyd算法 二.Floyd算法的应用 1. 传递闭包 例1:P2881 [USACO07MAR]排名的牛Ranking the Cows 例2:P2419 [USACO08JAN]牛大赛 ...

  7. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十四)之Type Information

    Runtime type information (RTTI) allow you to discover and use type information while a program is ru ...

  8. L4文本预处理

    文本预处理 timemachine.txt数据下载地址 链接:https://pan.baidu.com/s/1RO2OLyTRQZ90HJUW7V7BCQ 提取码:bjox NLTK数据集下载 链接 ...

  9. 如何将你的 Vue.js 项目部署在云开发静态托管之上

    云开发静态托管是云开发提供的静态网站托管的能力,静态资源(HTML.CSS.JavaScript.字体等)的分发由腾讯云对象存储 COS 和拥有多个边缘网点的腾讯云 CDN 提供支持. 在云开发静态托 ...

  10. 今天探究的CSS属性是box-sizing;

    首先BOX-SIZING属性是CSS3的属性: 语法: box-sizing : content-box || border-box || inherit 取值说明 1.content-box:此值为 ...