矩阵

线性代数的计算:

其中cij为a中第i竖列与b中第j横行对应乘积的合

如:c11=a11*b11+a21*b12+…+an1*b1n

cij=a1i*bj1+a2i*bj2+…+ani*bjn

矩阵:

对于上述计算中的集合a,b,我们可以称之为矩阵

矩阵乘法:

f(n)=f(n-1)+f(n-2)

这个是我们所熟知的斐波那契数列

在我们已知f(1),f(2)的情况下要求f(n)的值

一般来说,我们会直接从第一个算到第n个,这是传统思路

现在暂时忘记这种方法,假设我们有矩阵A

满足[f(n-1),f(n-2)]*A=[f(n),f(n-1)]

由于f(n)=f(n-1)+f(n-2)

所以可以写成:[f(n-1),f(n-2)]*A=[f(n-1)+f(n-2),f(n-1)]

用线性代数求出

矩阵A=

1 1

1 0

代码实现:

a[ ][ ],b[ ][ ],tmp[ ][ ]表示三个矩阵的值,n表示行列

const int N=10;

int tmp[N][N];

void multi(int a[][N],int b[][N],int n)

{

    memset(tmp,0,sizeof tmp);

    for(int i=0;i<n;i++)

    for(int j=0;j<n;j++)

    for(int k=0;k<n;k++)

        tmp[i][j]+=a[i][k]*b[k][j];

    for(int i=0;i<n;i++)

    for(int j=0;j<n;j++)

        a[i][j]=tmp[i][j];

}

计算会把矩阵a的值改变为结果,直接取a的值即可

当然,这种程度的代码实用性不高,和递推的复杂度一样都是O(n)

矩阵快速幂:

稍微温习一下普通快速幂

pow(int a,int b,int c)  a底数,b次方,对c取模

{

int ret=0;

while(b)

{

   if(b&1)

   ret=(ret*a)%mod;

   a=a*a;

b>>=1

}

}

将这个思想运用到矩阵当中便是矩阵快速幂:

int res[N][N];

void Pow(int a[][N],int n)

{

    memset(res,0,sizeof res);//n是幂,N是矩阵大小

    for(int i=0;i<n;i++) res[i][i]=1;

    while(n)

    {

        if(n&1)

            multi(res,a,N);//res=res*a; (此处用到的multi是上面计算矩阵的函数)

        multi(a,a,N);//a=a*a

        n>>=1;

    }

}

原文地址:https://www.cnblogs.com/qq936584671/p/8849314.html