Fibonacci Sequence
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的更多相关文章
- 【每天一题ACM】 斐波那契数列(Fibonacci sequence)的实现
最近因为一些原因需要接触一些ACM的东西,想想写个blog当作笔记吧!同时也给有需要的人一些参考 话不多说,关于斐波那契数列(Fibonacci sequence)不了解的同学可以看看百度百科之类的, ...
- ***1133. Fibonacci Sequence(斐波那契数列,二分,数论)
1133. Fibonacci Sequence Time limit: 1.0 secondMemory limit: 64 MB is an infinite sequence of intege ...
- python实现斐波那契数列(Fibonacci sequence)
使用Python实现斐波那契数列(Fibonacci sequence) 斐波那契数列形如 1,1,2,3,5,8,13,等等.也就是说,下一个值是序列中前两个值之和.写一个函数,给定N,返回第N个斐 ...
- 用递归方法计算斐波那契数列(Recursion Fibonacci Sequence Python)
先科普一下什么叫斐波那契数列,以下内容摘自百度百科: 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因意大利数学家列昂纳多·斐波那契(Leonardoda Fibonacci ...
- [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 ...
- SQL Server ->> 斐波那契数列(Fibonacci sequence)
斐波那契数列(Fibonacci sequence)的T-SQL实现 ;WITH T AS ( AS BIGINT) AS curr, CAST(NULL AS BIGINT) AS prv UNIO ...
- python3 求斐波那契数列(Fibonacci sequence)
输出斐波那契数列的前多少个数. 利用函数 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan # ----斐波那契数列( ...
- LeetCode 842. Split Array into Fibonacci Sequence
原题链接在这里:https://leetcode.com/problems/split-array-into-fibonacci-sequence/ 题目: Given a string S of d ...
- Computational Complexity of Fibonacci Sequence / 斐波那契数列的时空复杂度
Fibonacci Sequence 维基百科 \(F(n) = F(n-1)+F(n-2)\),其中 \(F(0)=0, F(1)=1\),即该数列由 0 和 1 开始,之后的数字由相邻的前两项相加 ...
- fibonacci number & fibonacci sequence
fibonacci number & fibonacci sequence https://www.mathsisfun.com/numbers/fibonacci-sequence.html ...
随机推荐
- 【php】COOKIE和SESSION
一. COOKIE(小甜点,小饼干) a) 生活中的实例: i. 大保健的会员卡(记录你的姓名.性别.ID号码.手机号……) ii. 超市的会员卡(记录你的姓名,性别,会员积分) b) PHP当中的实 ...
- 微信小程序--分享功能
微信小程序--分享功能 微信小程序前段时间开放了小程序右上角的分享功能, 可以分享任意一个页面到好友或者群聊, 但是不能分享到朋友圈 这里有微信开发文档链接:点击跳转到微信分享功能API 入口方法: ...
- (js描述的)数据结构 [数组的一些补充](1)
(js描述的)数据结构 [数组的一些补充](1) 1. js的数组: 1.优点:高度封装,对于数组的操作就是调用API 2.普通语言的数组: 1.优点:根据index来查询,修改数据效率很高 2.缺点 ...
- webstorm 永久激活方法
打开终端,执行: cd /etc/ sudo vim hosts 在最后一行加上: 0.0.0.0 account.jetbrains.com 打开webstorm,选择Activation Code ...
- Pytest系列(17)- pytest-xdist分布式测试的原理和流程
pytest-xdist分布式测试的原理 前言 xdist的分布式类似于一主多从的结构,master机负责下发命令,控制slave机:slave机根据master机的命令执行特定测试任务 在xdist ...
- 理解JSON:3分钟课程
理解JSON:3分钟课程 博客分类: Java综合 jsonAjaxJavaScriptXMLLISP 本文是从 Understanding JSON: the 3 minute lesson 这篇文 ...
- JSR303完成validate校验并编写BeanValidator工具类
一.引入pom依赖 <!-- validator --> <dependency> <groupId>javax.validation</groupId> ...
- 【题解】LOJ2462完美的集合(树DP 魔改Lucas)
[题解]LOJ2462完美的集合(树DP 魔改Lucas) 省选模拟考这个??????????????????? 题目大意: 有一棵树,每个点有两个属性,一个是重量\(w_i\)一个是价值\(v_i\ ...
- work of 1/5/2016
part 组员 今日工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云 UI页面切换,词本显示下滑条 6 继续下滑条等增删补 ...
- docx4j docx转html
不好用,转完问题挺多,百度还找不到资料头疼.public static void docxToHtml(String fileUrl) throws Exception { String path = ...