码迷,mamicode.com
首页 > 其他好文 > 详细

矩阵乘法优化dp

时间:2018-06-16 18:49:48      阅读:409      评论:0      收藏:0      [点我收藏+]

标签:iostream   技术   oid   斐波那契   而且   none   space   快速幂   img   

矩阵乘法优化dp

  前几天学姐说要给我们考矩乘dp和期望dp...其实我们都(也可能只有我)不会。

  那只能现学了,然而学了一天突然通知不考了qwq

 

矩阵乘法

  A矩阵为m*k,B矩阵为k*n,两矩阵相乘则得C矩阵为m*n;

技术分享图片
for (int i=1;i<=M;++i)
    for (int j=1;j<=N;++j)
        for (int k=1;k<=K;++k)
            c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
矩阵乘法模板

    时间复杂度为$O(N^3)$,数学一本通上提到了一种奇妙的矩阵乘法$Strassen:O(N^{2.81})$,但是非常非常复杂非常非常难写,于是就不写了(而且我也不会);

 

矩阵快速幂

  其实和数字快速幂的思想是一样的。有一个小技巧:如果一个矩阵的主对角线全为1,其他部分为0,对于另一个矩阵来说就相当于单位元,相乘不变;

  矩阵快速幂:https://www.luogu.org/problemnew/show/P3390

   技术分享图片
# include <cstdio>
# include <iostream>

using namespace std;

const int P=1e9+7;
struct s
{
    long long a[101][101];
}A,ans;
long long k;
int n;

s mul(s a,s b)
{
    s c;
    for (int i=1;i<=n;i++)
      for (int j=1;j<=n;j++)
        c.a[i][j]=0;
    for (int i=1;i<=n;i++)
      for (int j=1;j<=n;j++)
        for (int k=1;k<=n;k++)
          c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%P)%P;
    return c;
}

void qui (long long k)
{
    while (k)
    {
        if(k&1) ans=mul(ans,A);
        A=mul(A,A);
        k=k>>1;
    }
    return ;
}

int main()
{
    scanf("%d%lld",&n,&k);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            scanf("%lld",&A.a[i][j]);
    for (int i=1;i<=n;i++)
      for (int j=1;j<=n;j++)
        if(i==j) ans.a[i][j]=1;
    qui(k);
    for (int i=1;i<=n;i++)
    {
      for (int j=1;j<=n;j++)
        printf("%lld ",ans.a[i][j]);
      printf("\n");
    }
    return 0;
}
矩阵快速幂

 

矩乘优化数列递推

  矩阵乘法可以用来加速线性的递推式(也许也可以加速别的递推吧),思路非常棒;

  首先构造一列数列,保存与递推$f[n]$有关的项,以斐波那契数列为例:

  $f[n]=f[n-1]+f[n-2]$ 所以构造的矩阵为

      $\begin{bmatrix}
f[n-1] \\
f[n-2]
\end{bmatrix}$

 

  

  

 

矩阵乘法优化dp

标签:iostream   技术   oid   斐波那契   而且   none   space   快速幂   img   

原文地址:https://www.cnblogs.com/shzr/p/9190970.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!