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. [SCF+wetest+jmeter]简单云性能压测工具使用方案

    前言 压测太难?局域网压力无法判断服务器网络指标?无法产生非常大的并发量?云性能太贵? 也许我们可以把各种简单的工具拼起来进行压力测试! 准备 https://cloud.tencent.com/pr ...

  2. DataAnalysis-SOP

    一.关于数据分析 a. 互联网最热职位:研发工程师.产品经理.人力资源.市场营销.运营.数据分析(供不应求) b. 数据分析的步骤:明确目的/思路.数据收集.数据处理.数据分析.数据展现 c. 数据分 ...

  3. SQL——语法基础篇(上)

    用数据库的方式思考SQL是如何执行的 虽然 SQL 是声明式语言,我们可以像使用英语一样使用它,不过在 RDBMS(关系型数据库管理系统)中,SQL 的实现方式还是有差别的.今天我们就从数据库的角度来 ...

  4. animation-play-state 在 ios 中不生效的解决办法(JS篇)

    我们要实现动画的播放和暂停,animation-play-state 在安卓端可以使用,但是在 ios 中不起作用,这时可以使用 js 来实现相同效果. 原理 通过 js 获取当前元素的 transf ...

  5. 通过神秘代码登录自己的QQ

    通过神秘代码登录自己的QQ 如图:是怎么做成的呢? 其实很明显,这个是QQ号码的16进制 所以网上搜索进制转换打开一个网页 输入自己的QQ号码,得到16进制的QQ号码 在QQ页面账号处先添加0x然后复 ...

  6. window 10 安装paddlepaddle 1.7 GPU版本

    window 10 安装paddlepaddle 1.7 GPU版本 1)更新显卡驱动 2)安装cuda 10 https://developer.nvidia.com/cuda-10.0-downl ...

  7. 无序map 记录一下

    unordered_map<int ,int >mp; unordered_map是基于hash表实现的,查找元素的复杂度可以达到o(1),查找n个元素,复杂度为o(n). map是基于红 ...

  8. Matlab学习-(2)

    1. 文件读取 在编写一个matlab项目时候,通常要导入很多不同格式的数据,下面我们来学习不同的导入函数.(1) 保存工作区MATLAB支持工作区的保存.用户可以将工作区或工作区中的变量以文件的形式 ...

  9. Python 实用冷门知识整理

    1.print 打印带有颜色的信息 大家知道 Python 中的信息打印函数 print,一般我们会使用它打印一些东西,作为一个简单调试. 但是你知道么,这个 Print 打印出来的字体颜色是可以设置 ...

  10. 纯css画三角形

    纯css画三角形与border元素相关 设置border的属性 width: 100px; height: 100px; border-style: solid; border-width: 100p ...