• 二:矩阵快速幂


    改编自:地址

    第一篇介绍了如何快速求幂,这一篇介绍如何用数字快速求幂的思想,来快速求矩阵之幂

    这是求矩阵A、B乘积的代码:

    const int N=100;
    int c[N][N];
    void multi(int a[][N],int b[][N],int n)
    {
        memset(c,0,sizeof c);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
            c[i][j]+=a[i][k]*b[k][j];
    }

    这里我直接写的是n*n的矩阵(即方阵),显然两个相乘是要一行和一列对应乘,那么矩阵乘法是需要A的行数与B的列数相等的(这是A*B的前提条件,可见矩阵的乘法是不满足交换律的)。然而这些一般都是没什么用的,矩阵快速幂只会用到方阵(除非题目是裸的矩阵乘法)。矩阵快速幂都是方阵也就避免的相乘的前提条件,可以放心用。

    OK,现在可以求两个矩阵之积,那么矩阵的“平方”和“幂”也就可以求,下面就是矩阵如何快速求幂,和第一篇的思想相同

    需要用到一个小知识就是:单位矩阵与矩阵A相乘,结果仍是矩阵A

    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=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
            tmp[i][j]+=a[i][k]*b[k][j];
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            a[i][j]=tmp[i][j];
    }
    int res[N][N];
    void Pow(int a[][N],int n)
    {
        memset(res,0,sizeof res);
        for(int i=1;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;
        }
    }

    如上,在最后结果存在res里,如果觉得不爽也可以在pow函数的最后加一个复制,把res复制给a

     将n次矩阵相乘减少到logn次,这就是矩阵快速幂的核心妙处

    通过将其他问题转化为“求矩阵之幂”,进而运用快速幂的思想求出结果

    那么,你会问,怎么会有求“矩阵之幂“这种无聊的问题呀?嘿,还真有

    前两篇是基础,第三篇开始实例

    据知后事如何,请看下回分解

    柳暗花明又一村
  • 相关阅读:
    力扣 227 :基本计算器(II)
    力扣 224 :基本计算器(I)
    力扣 888:公平的糖果棒交换(哈希表法)
    力扣 1047 :删除字符串中的所有相邻重复项
    力扣 1423 :可获得的最大点数
    vue+spreadjs+后台Java实现与服务端交互的导入导出
    webpack 中 require.context() 多个模块的加载
    dwd_fact_coupon_use
    dwd_fact_cart_info
    dwd_fact_order_detail
  • 原文地址:https://www.cnblogs.com/ucandoit/p/8645931.html
Copyright © 2020-2023  润新知