斐波那契数列--编程之美(待完善)
来源:互联网 发布:数控车床编程图文实例 编辑:程序博客网 时间:2024/04/27 22:04
解法三:分治策略:
注意到Fibonacci数列是二阶递推数列,所以存在一个2*2的矩阵A,使得:(F[n] F[n-1])=(F[n-1] F[n-2])*A,结合F[n]=F[n-1]+F[n-2]求解,可得:A=1 1,1 0(上面是1 1,下面为1 0),由上面的矩阵递推公式有:(F[n] F[n-1])=(F[n-1] F[n-2])*A=(F[n-2] F[n-3])*A^2=...=(F[1] F[0])*A[n-1],或
.
剩下的问题就是求解矩阵A的方幂。A^n=A*A*...*A,最直接的解法就是通过n-1次乘法得到结果。但是当n很大时,比如1 000 000或1 000 000 000,这个算法的效率就不能接受了。当然,在这个情况下,F[n]在int所表示的整数里早就溢出了,但如果要求解的是F[n]对某个素数的余数时,这个算法会是非常有用和高效的。
注意到:
A^(x+y)=A^x*A^y
A^(x*2)=A^(x+x)=(A^x)^2
用二进制方法表示n:
n=ak*2^k+a(k-1)*2^(k-1)+...+a1*2+a0(其中ai=0或1,i=0,1,...,k)
A^n=A^(ak*2^k+a(k-1)*2^(k-1)+...+a1*2+a0)=(A^(2^k))^ak*...*A^a0
如果能够得到A^(2^i)的值,就可以再经过logn次乘法得到A^n.
而这容易通过递推得到:
A^(2^i)=(A^(2^(i-1)))^2。根据上面的思想,具体代码如下:
Class Matrix; //假设我们已经有了实现乘法操作的矩阵类
Matrix MatrixPow(const Matrix &m,int n){ //求解m的n次方
Matrix result=Matrix::Identity; //赋初值为单位矩阵
Matrix tmp=m;
for(;n;n>>=1){
if(n&1)result*=tmp;
tmp*=tmp;
}
}
int Fibonacci(int n){
Matrix an=MatrixPow(A,n-1); //A的值就是上面求解出来的
return F1*an(0,0)+F0*an(1,0);
}
整个算法的时间复杂度为O(logn)
转自:http://www.cnblogs.com/yujunyong/articles/2017468.html- 斐波那契数列--编程之美(待完善)
- 编程之美之斐波那契数列
- 编程之美_008斐波那契数列
- 编程之美2.9----斐波那契数列
- [编程之美] PSet2.9 斐波那契数列
- 编程之美2.9 斐波那契数列
- 编程之美 2.9 斐波那契(Fibonacci)数列
- 编程之美2.9斐波那契数列
- 编程之美2.9 斐波那契数列
- 读书笔记之编程之美 - 2.9 斐波那契(Fibonacci)数列
- 编程之美: 第二章 数字之魅 2.9斐波那契数列
- 编程之美2.9——斐波那契数列
- 编程之美读书笔记2.9—斐波那契数列
- 编程之美-斐波那契(Fibonacci)数列方法整理
- 编程之美2.9-斐波那契(Fibonacci)数列
- 编程之美 裴波那楔数列
- 编程题之斐波那契数列分解
- 编程题目:斐波那契数列
- Android ApiDemos示例解析(134):Views->Layouts->Baseline->2. Bottom
- 2012谷歌浏览器的逆袭
- C# 常用正则表达式
- Android ApiDemos示例解析(135):Views->Layouts->Baseline->3. Center
- jquery表单
- 斐波那契数列--编程之美(待完善)
- 自制的android多渠道应用打包工具--RyApkTool(1)
- Android ApiDemos示例解析(136):Views->Layouts->Baseline->4. Everywhere
- 《The 3G IP MultiMedia Subsystem -- merging the INTERNET and the cellular worlds》
- Android ApiDemos示例解析(137):Views->Layouts->Baseline->5. Multi-line
- xss
- JS操作JSON总结
- Android ApiDemos示例解析(138):Views->Layouts->Baseline->6. Relative
- mysql查询今天、昨天、7天、近30天、本月数据