斐波那契数列 矩阵求法 优化
来源:互联网 发布:淘宝无法开店 编辑:程序博客网 时间:2024/05/22 04:49
在做编程题目的时候经常会遇到“斐波那契数列”相关的题目,尤其在做OJ中。下面说一些方法:
(一)递归
递归是最慢的会发生重复计算,时间复杂度成指数级。
(二)循环
利用临时变量来保存中间的计算过程,加快运算。
(三)矩阵乘法+空间换时间(减少乘法,取模运算)
数列的递推公式为:f(1)=1,f(2)=2,f(n)=f(n-1)+f(n-2)(n>=3)
用矩阵表示为:
进一步,可以得出直接推导公式:
由于矩阵乘法满足结合律,在程序中可以事先给定矩阵的64,32,16,8,4,2,1次方,加快程序的执行时间。(有些题目需要取模运算,也可以事先进行一下)。给定的矩阵次幂,与二进制有关是因为,如下的公式存在解,满足Xi={0或1}:
为了保证解满足 Xi={0或1},对上述公式的求解从右向左,即求解顺序为Xn,Xn-1,Xn-2,....,X1,X0。
完整代码实现如下:
#include <stdio.h>#include <stdlib.h>#include <math.h>/**先用一个数组保存1 11 0矩阵n次幂的值,这样可以提高运行效率*/long long fac_tmp[7][4]={ {1,1,1,0},///1 0 {2,1,1,1},///2 1 {5,3,3,2},///4 2 {34,21,21,13},///8 3 {1597,987,987,610},///16 4 {24578,78309,78309,46269},///32 5 {77565,57723,57723,19842} ///64 6};int mod=100000;/**计算第k个斐波那契数,用来求数组void get(int k) { for(int i=k; i>=0; --i) { a=(t00*fac_tmp[0][0]+t01*fac_tmp[0][2])%mod; b=(t00*fac_tmp[0][1]+t01*fac_tmp[0][3])%mod; c=(t10*fac_tmp[0][0]+t11*fac_tmp[0][2])%mod; d=(t10*fac_tmp[0][1]+t11*fac_tmp[0][3])%mod; t00=a; t01=b; t10=c; t11=d; } printf("%d:\n",k+2); printf("%I64d,%I64d,%I64d,%I64d\n",a,b,c,d); a=(t00*2+t01*1)%mod; return a; } }**/void fac(int k){ int i,ok=k; long long t00=1,t01=1,t10=1,t11=0; long long a=1,b=1,c=1,d=0; if(k==1) a=1; else if(k==2) a=2; else { k=k-3; if(k>64) { for(i=k; i>=64; i-=64) { a=(t00*fac_tmp[0][0]+t01*fac_tmp[0][2])%mod; b=(t00*fac_tmp[0][1]+t01*fac_tmp[0][3])%mod; c=(t10*fac_tmp[0][0]+t11*fac_tmp[0][2])%mod; d=(t10*fac_tmp[0][1]+t11*fac_tmp[0][3])%mod; t00=a; t01=b; t10=c; t11=d; } } i=5; while(i>=0) { if(k>=(long long)pow(2,i)) { a=(t00*fac_tmp[i][0]+t01*fac_tmp[i][2])%mod; b=(t00*fac_tmp[i][1]+t01*fac_tmp[i][3])%mod; c=(t10*fac_tmp[i][0]+t11*fac_tmp[i][2])%mod; d=(t10*fac_tmp[i][1]+t11*fac_tmp[i][3])%mod; t00=a; t01=b; t10=c; t11=d; k=k-(int)pow(2,i); } i--; } a=(t00*2+t01*1)%mod; } printf("Fab(%d) = %I64d\n",ok,a);}int main(){ int k; while(scanf("%d",&k)!=EOF) { fac(k); printf("\n"); } return 0;}
转自 :旭东的博客
1 0
- 斐波那契数列 矩阵求法 优化
- 菲波那契数列的快速幂矩阵求法
- 斐波那契数列的矩阵分治求法java实现
- poj3070 Fibonacci 斐波那契数列的第n项的矩阵求法
- 斐波那契数列的矩阵求法,效率O(lgn)
- 斐波那契数列的各种求法
- 斐波那契数列通项公式的求法
- 斐波那契数列高效递归求法
- 斐波那契(Fibonacci)数列的求法
- 斐波那契数列的三种求法
- 斐波那契数列的几种求法
- 斐波那契数列的各种求法
- 矩阵-斐波那契数列
- 矩阵专题:斐波那契数列
- 矩阵-斐波那契数列
- 斐波那契数列-矩阵乘法
- 矩阵与斐波那契数列
- 51nod--1242 斐波那契数列第N项 (矩阵乘法优化)
- 平方和与立方和hdu2007
- AbstractQueuedSynchronizer的介绍和原理分析
- 小事
- 关于反爬虫,看这一篇就够了
- 【淘淘】Spring整合Quartz框架
- 斐波那契数列 矩阵求法 优化
- android不断开关蓝牙
- rgba中的a是指?CSS之RGBA颜色指南
- 警告:不能读取 AppletViewer 的属性文件解决
- SQLserver学习day08 视图和索引
- NYoj 906杨辉三角(二维数组)
- 勾选问题
- [2016/12/6]计算两个大数的和
- C# 如何关联键盘按钮 (KeyChar/KeyCode值 KeyPress/KeyDown事件 区别)