程序设计实习递归练习 矩阵快速幂求斐波那契数列

来源:互联网 发布:雅思培训网络课程 编辑:程序博客网 时间:2024/05/17 02:19

程序设计实习递归练习 矩阵快速幂求斐波那契数列

这是来自程序设计实习课堂上的趣味练习,非常有意思,而且矩阵快速幂也是早该掌握的方法。

趣味思考题:菲波那契数列的计算
递归:O(N)
递推:O(N)
问题:给出一种时间复杂度低于O(N)的解法,例如O(log2 N)甚至O(1)?
当N=2的60次方时如何计算?

选自《编程之美——微软技术面试心得》

除了矩阵快速幂还有其他方法。比如直接快速幂,其中sqrt(5)当作符号保留,复杂度O(log2 n)。如果数据较小,不必担心精度,可以直接计算幂次,用取对数计算,复杂度O(1)。

运用矩阵乘法描述递推关系,这样就可以实现把下标增长转化为矩阵的幂次,再快速幂加速
递推方程式为 (a(n+1),a(n+2))’=((0,1),(1,1))* (a(n),a(n+1))’=(a[1])^n*(1,1)’

类似的题目还有高精度幂次快速幂——麦森数以及所有递推公式的方法

#define MAX_N 10#include<stdio.h>//(a(n+1),a(n+2))'=((0,1),(1,1))*(a(n),a(n+1))'=(a[1])^n*(1,1)'int a[MAX_N+1][2][2]={{{1,0},{0,1}},{{0,1},{1,1}}};int n;void cal(int n){    if (a[n][0][0]+a[n][0][0]+a[n][1][0]+a[n][1][1])        return;    if (n==1 || n==0)        return;    int i1=n>>1,i2=n-i1;    cal(i1);    cal(i2);    for (int k=0;k<2;k++)        for (int i=0;i<2;i++)             for (int j=0;j<2;j++)                a[n][i][j]+=a[i1][i][k]*a[i2][k][j];    return;}int main(){    for (int n=1;n<=MAX_N;n++)    {         cal(n-1);        printf("f(%d)=%d\n",n,a[n-1][1][1]);    }    return 0;}
0 0
原创粉丝点击