将递推式转换成矩阵优化

来源:互联网 发布:福彩快3源码 编辑:程序博客网 时间:2024/06/01 09:42

对于很多递推式取膜,在很大的数据的时候,直接递推其实效率并不高。如何将递推式与矩阵练习起来进行优化呢?
比如斐波拉契数列fn=fn1+fn2
我们可以将最终态写成一个一行n列的矩阵|fn fn1|
再将前一种状态也写出来作为等号右边的矩阵|fn1 fn2|
所以我们可以构造一个矩阵使得矩阵相乘成立。fn=|fn1 fn2|矩阵的第一列。所以第一列是1,1。fn1= |fn1 fn2|矩阵的第二列,所以第二列是1,0,所以综合后矩阵为|1 1,1 0|之后再同理递推到最开始的几项。
详细的见图理解一下就会了。。。

这里写图片描述

随便附上矩阵的运算模板

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>using namespace std;#define MOD 1000000007struct Mat{    int n,m;   //行列    int mat[19][19];};Mat operator *(Mat a,Mat b){  //矩阵相乘    Mat c;    memset(c.mat,0,sizeof(c.mat));    c.n = a.n,c.m = b.m;    for(int i=1;i<=a.n;i++){        for(int j=1;j<=b.m;j++){            for(int k=1;k<=a.m;k++){                    c.mat[i][j] += (a.mat[i][k]*b.mat[k][j])%MOD;                    c.mat[i][j] %= MOD;            }        }    }    return c;}Mat operator +(Mat a,Mat b){ //矩阵相乘    Mat c;    memset(c.mat,0,sizeof(c.mat));    c.n = a.n,c.m = a.m;    for(int i=1;i<=a.n;i++){        for(int j=1;j<=a.m;j++){            c.mat[i][j] = (a.mat[i][j]+b.mat[i][j])%MOD;        }    }    return c;}Mat operator ^(Mat a,int k){   //矩阵幂    Mat c;    memset(c.mat,0,sizeof(c.mat));    c.n = a.n,c.m = a.n;    for(int i=1;i<=a.n;i++)c.mat[i][i] = 1;    while(k){        if(k&1){            c = c*a;        }        a = a*a;        k>>=1;    }    return c;}void out(Mat a){      //输出矩阵    for(int i=1;i<=a.n;i++){        for(int j=1;j<=a.m;j++){            printf(j==a.m? "%d\n":"%d ",a.mat[i][j]);        }    }}int main(){    Mat d;    d.n=3,d.m=3;    for(int i=1;i<=d.n;i++){        for(int j=1;j<=d.m;j++){            scanf("%d",&d.mat[i][j]);        }    }    d=d^2;    out(d);}
0 0
原创粉丝点击