浅谈斐波那契数列——从递推到矩阵乘法
说在前面
相信大家都已经知道这个中外著名的费波纳切数列了吧,关于费波那契数列有很多有趣的性质,但我们这里不讲,在这里我们只是利用斐波那契数列来引出另一个神奇的东西,矩阵乘法,递推在这里是起一个对比与铺垫的作用,(没有对比就不知道矩阵乘法有多快)。
斐波那契数列
定义一个数列
F(n) = \begin{cases} 0, & \text{$n$=0 } \\ 1,& \text{$n$=1} \\ F_{n-1}+F_{n-2}, & \text{$n \ge 2$} \end{cases}
递推
递推(我当大家都会了),但是这样的做法时间复杂度是 O(n) O(n),的,当n很大时,这个算法就会T。
通项公式
斐波那契数列有一个通项公式,
F(n)=\frac{1}{\sqrt5}\times \left[\left(\frac{1+\sqrt5}{2}\right)^n-\left(\frac{1-\sqrt5}{2})\right)^n \right],直接用快速幂计算两个log,但是如果要取模怎么办?求一个非整数的逆元?通项公式似乎很难。
进入正题——矩阵乘法
知识预备:
①设
A=\begin{bmatrix}1 & 0& 2 \\-1 & 3 & 1 \\\end{bmatrix}
B=\begin{bmatrix}3 & 1 \\2 & 1 \\1 & 0 \\\end{bmatrix}
AB=\begin{bmatrix}(1\times3+0\times2+2\times1) & (1\times1+0\times1+2\times0) \\(-1\times3+3\times2+1\times1) & (-1\times1+3\times1+1\times0) \\\end{bmatrix}=\begin{bmatrix}5 & 1 \\4 & 2 \\\end{bmatrix}
②设
A=\begin{bmatrix}a & c \\b & d \\\end{bmatrix}
B=\begin{bmatrix}e \\f \\\end{bmatrix}
AB=\begin{bmatrix}ae+cf \\be+df \\\end{bmatrix}
有了这些东西,接下来就可以做斐波那契了,把相邻两项写在一个2*1的矩阵中,
\begin{align}\begin{bmatrix}F_n \\F_{n-1} \\\end{bmatrix}&=\begin{bmatrix}F_{n-1}+F_{n-2} \\F_{n-1} \\\end{bmatrix}\\&= \begin{bmatrix}F_{n-1} \times1+F_{n-2}\times1 \\F_{n-1}\times1+F_{n-2}\times0 \\\end{bmatrix}\\&= \begin{bmatrix}1 & 1 \\1 & 0 \\\end{bmatrix}\times\begin{bmatrix}F_{n-1} \\F_{n-2}\\\end{bmatrix}\\&=\begin{bmatrix}1 & 1\\1 & 0\\\end{bmatrix}^{n-1}\times\begin{bmatrix}F_1\\F_0\\\end{bmatrix}\\&=\begin{bmatrix}1 & 1\\1 & 0\\\end{bmatrix}^{n-1}\times\begin{bmatrix}1\\0\\\end{bmatrix}\end{align}
那么问题的本质,就是如何解决计算这一块
\begin{bmatrix}1 & 1\\1 & 0\\\end{bmatrix}^{n-1}
算完之后,取矩阵第一行第一列的元素,计算这个其实又是快速幂,说些什么呢?谢谢蒙格马利吧。
代码
快速幂:
function f(a,b:extended;n:int64):int64;
vart,y:extended;
begint:=1;y:=a;while b<>0 dobeginif(b and 1)=1 thent:=t*y mod n ;y:=y*y mod n;b:=b shr 1;end;exit(t);
end;
用快速幂求出斐波那契的第n项。
typematrix=array[0..1,0..1] of int64;
constmo=trunc(1e+8+7);
vara,ans:array[0..1] of int64;b,c,d:matrix;i,j,k:longint;n:int64;
procedure work(var a,b,c:matrix);//两个2*2的矩阵相乘
vari,j,k:longint;
beginfor i:=0 to 1 dobeginfor j:=0 to 1 dobeginfor k:=0 to 1 dobeginc[i,j]:=(c[i,j]+a[i,k]*b[k,j] mod mo) mod mo;end;end;end;
end;
procedure fastpower(x:int64);
beginc[0,0]:=1;c[0,1]:=1;c[1,0]:=1;c[1,1]:=0;b[0,0]:=1;//开始将B赋值为单位矩阵,相当于实数中1在乘法中的作用b[1,1]:=1;while x<>0 dobeginif (x and 1)=1 thenbeginfillchar(d,sizeof(d),0);work(b,c,d);b:=d;end;fillchar(d,sizeof(d),0);work(c,c,d);c:=d;x:=x div 2;end;
end;
beginreadln(n);if n=0 thenwriteln(0);if (n=1)or(n=2) thenwriteln(1);fastpower(n-1);a[0]:=1;a[1]:=0;for i:=0 to 1 dobeginfor j:=0 to 1 dobeginans[i]:=(ans[i]+a[j]*b[j][i] mod mo) mod mo;end;end;writeln(ans[0] mod mo);
end.
可以发现其实两者实质上是一样的,只是在计算的时候,一个用矩阵计算,另一个直接用一个变量计算,(矩阵其实也就是一堆变量)。
the end
由于我的水平有限,难免有些会写错的,希望大家多多包容,批评指正,谢谢。
浅谈斐波那契数列——从递推到矩阵乘法相关推荐
- 斐波那契数列的递推与递归求法
斐波那契数列的递推与递归求法: OVERVIEW 斐波那契数列的递推与递归求法: (1)递推求Fibonacci: (2)递归求Fibonacci: (3)递归求Fibonacci(记忆化数组优化): ...
- 斐波拉契数列的递推递归求解算法
介绍: 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为"兔子数 ...
- c语言斐波那契数列_从数学角度浅谈斐波那契数列
斐波那契数列历史由来已久,关于这个算法的方式也有很多,这篇讲一个由最复杂到最简单的转化. 该文主要从数学角度出发粗略谈谈. Fibonacci数列递推式为: 下面从数学角度思考这个问题,你应该还记得, ...
- 斐波拉契数列C++--递推
[问题描述] 有斐波拉契数列1,1,2,3,5,8,13--,请按每行m个数据输出该裴波拉契数列的前n项,其中m,n从键盘输入 [输入形式] m为1-7之间的整数,n值是1-50之间的任意一整数. [ ...
- 奶牛家族(斐波那契数列的快速幂乘矩阵算法)
TX面试题: 已知有一头牛4年后开始生小牛,一次只能生一只,问20年后一共有多少头牛? 这种问题就是简单的递归: 这头奶牛在第四年后能不断生子直到第二十年,其子出生4年后又能不断生子-- 代码如下: ...
- 算法提高课-数学知识-矩阵乘法-AcWing 1303. 斐波那契前 n 项和:矩阵乘法,快速幂,线性代数
题目分析 来源:acwing 分析: 先利用矩阵运算的性质将通项公式变成幂次形式,然后用快速幂的方法求解第 n项. 斐波那契数列的递推公式:f1=f2=1,fn=fn−2+fn−1(n≥3)f_1 = ...
- 由递推关系式用差分方程的方法得到通项公式实现求斐波那契数列的第n项;迭代、递归、栈、差分方程之间的本质联系以及由推广的迭代法解决“变态青蛙跳台阶”问题;汉诺塔问题的数字特征以及用递归解决的原理推导。
最近几天在研究算法中一个比较基础且突出的问题,就是关于"递推关系式.递归.迭代.序列前k项和"之间的区别与联系. 一.斐波那契数列与差分方程 首先我们考察一个经典的算法,求斐波那契 ...
- 快速幂与快速矩阵幂(以大数下的斐波那契数列为例)
一般地,a^n的算法时间复杂度为o(n),但是如果n为大数,则运行时间过长,效率不高.因此,使用二分的思想降低时间复杂度,使其降至o(logn),则会使运行效率较大提升.二分思想如下图所示. 例如:2 ...
- 求斐波那契数列的第n项
提要 本文介绍了4种(3种?)求斐波那契数列第n项的方法. 斐波那契数列简介 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda ...
最新文章
- 【Linux】在虚拟机上安装CentOS7
- 最新 主流笔记本cpu列表
- 影响PoE交换机不稳定的因素
- ios 使用webview 查找_iOS开发WKWebView与JS的交互
- Eclipse自动部署项目到Tomcat的webapps下的有效方法
- java addslashes_PHP防止注入攻击
- 【题解:洛谷4186||USACO18JAN Cow at Large G】
- n维向量,n维向量空间,n维向量空间的维数
- 4核处理器_AMD新款4核处理器899元,配一套电脑是不是可以更便宜了?
- Opencv中的图像相加,相减,相除,相乘(python实现)
- Docker Desktop启动失败(Docker failed to initialize Docker Desktop is shutting down)
- Nape刚体body.align();
- C# chart1 添加滚动条的缩放 鼠标滚轮控制缩放
- 使用树莓派制作一套“NAS+私有云盘+下载机”
- matlab获取等高线的坐标,[matlab数据拟合曲线]matlab获取等高线的数据
- ora-28040解决方法
- 压缩软件不同,如何删除压缩包密码
- Node.js MySQL连接数据库 Error: Cannot enqueue Handshake after invoking quit.
- ARM | STM32F10xxx课堂学习笔记(时钟 高级控制定时器)...
- Cesium.JS Google Earth 历史影像获取
热门文章
- 【Tomcat】——纯手写实现一个简单的Tomcat
- eHR系统和OA系统有什么不同?
- CSS3之转换(2D转换,动画,3D转换)
- MySQL 统计过去12个月的数据(包括本月)
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四十四)制作主角属性面板及加点器
- mysql5.7 百度云_mysql5.7 安装版本配置教程+百度云资源分享
- 长文预警!吐血总结2万字Java容器,再也不怕面试官刨根问底了。
- Thinphp集成抖音SDK
- JS买股票的最好时机
- 封装一个新闻类News,包含新闻标题,新闻作者,新闻内容,新闻类型三个属性,提供必要的访问器和修改器方法重写toString方法,要求打印对象时输出格式为“标题;