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. 【数据库】MySQL数据库(五)

    一.DCL语句 1.添加权限: '; 注:sakili为数据库名,z1为新创建的数据库用户,123为密码 数据库添加权限 2.权限收回: revoke insert on sakila.* from ...

  2. MyBatis(八):高级结果映射

    本文是按照狂神说的教学视频学习的笔记,强力推荐,教学深入浅出一遍就懂!b站搜索狂神说或点击下面链接 https://space.bilibili.com/95256449?spm_id_from=33 ...

  3. python 删除三天前的日志.py

    #获取所有文件def file(): for cur_dir, dirs, files in os.walk(r'/学习/接口自动化/BestTest/作业/logs'): # cur_dir(当前路 ...

  4. ElasticSearch 常用查询语句

    为了演示不同类型的 ElasticSearch 的查询,我们将使用书文档信息的集合(有以下字段:title(标题), authors(作者), summary(摘要), publish_date(发布 ...

  5. Linux中vim编辑器 的 快捷键 --- 常用 的 都比较全

    Linux中vim编辑器的功能非常强大,许多常用快捷键用起来非常方便,这里将我学vim入门时学的一些常用的快捷键分享给大家一下,希望可以帮助你们. 这个是我将鸟哥书上的进行了一下整理的,希望不要涉及到 ...

  6. webWMS开发过程记录(一)- 软件开发的流程

    前言:计划开发一个webWMS,并将开发过程比较完整的记录下来.希望可以完成这个目标 软件开发的流程: 1. 了解该项目的相关概念. 了解所要开发的软件属于什么产品.该产品的基本定义是什么?基本功能模 ...

  7. 用threejs实现三维全景图

    网络上看到了3D全景图,发现threejs里面有一个库竟然可以实现,一下我贴出代码: <!DOCTYPE html> <html> <head> <meta ...

  8. day22作业

    # 1.检索文件夹大小的程序,要求执行方式如下 # python3.8 run.py 文件夹 import os,sys l = sys.argv[1] size = 0 def get_size(f ...

  9. work of 12/30/2015

    part 组员                今日工作              工作耗时/h 明日计划 工作耗时/h    UI 冯晓云   merge UI 与reader     6  丰富re ...

  10. JavaScript基础笔记1220

    JavaScript笔记1.JavaScript关键词2.JavaScript标识符 必须以字母,下划线(_)或美元符($)开始. 后续的字符可以是字母.数字.下划线或者美元符 (数字是不允许作为首字 ...