矩阵优化dp

本文探讨了如何利用快速幂算法优化矩阵乘法,通过将乘法次数降至对数级别,减少重复计算。同时,介绍将矩阵乘法问题与二进制表示相结合,提高计算效率。通过实例和P3390模板,展示了矩阵快速幂在实际问题中的应用和代码实现。
摘要由CSDN通过智能技术生成

矩阵快速幂

矩阵乘法

矩阵 A , B A,B A,B规模分别为 n × s , s × m n×s,s×m n×s,s×m,要进行矩阵乘法, A , B A,B A,B满足条件为"前列数=后行数"。 C C C A , B A,B A,B矩阵乘法结果,则C的规模变成 n × m n×m n×m, C C C i i i行第 j j j列的数字为A第i行每k个数乘B第j列每k个数: C ( i , j ) = ∑ k = 1 k = s A ( i , k ) × B ( k , j ) C(i,j)=\sum_{k=1}^{k=s}{A(i,k)×B(k,j)} C(i,j)=k=1k=sA(i,k)×B(k,j)

快速幂

如果要算3的21次方,不做任何优化: 3 × 3 = 9 , 9 × 3 = 27 , 27 × 3 = 81... 3×3=9,9×3=27,27×3=81... 3×3=9,9×3=27,27×3=81...一共做21次。
但是其实里面有很多重复计算的地方。让我们把21转化成2进制: ( 10101 ) 2 (10101)_2 (10101)2观察。
如下图:
在这里插入图片描述
将21的二进制最后一位称作第一位,第一位是1,那答案包含 3 ( 1 ) 2 3^{(1)_2} 3(1)2,接下来计算 3 ( 100 ) 2 3^{(100)_2} 3(100)2,我们发现 ( 100 ) 2 (100)_2 (100)2 ( 1 ) 2 (1)_2 (1)2左移2位,体现在底数,就是底数自乘2次。只要让3不断自乘,同时幂数不断右移,当幂数最后一位是1时,就将当前的底数乘到答案上即可。以上算法的时间复杂度是O(log幂数),因为n转化成二进制时的长度为log幂数。
设底数为a,幂数为b,一般答案会很大,一般会给你一个模数,在每次算出答案均取模。代码如下:

LL ksm(LL a,LL b){
    LL ans=1;
    while(b){
        if(b&1)
            ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}

P3390 【模板】矩阵快速幂

题目链接

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=110,mod=1e9+7;
int n;
struct Matrix{
    LL x[N][N];
    Matrix(){
        memset(x,0,sizeof x);
    }
};
Matrix operator*(const Matrix &a,const Matrix &b){
    Matrix tmp;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        	for(int k=0;k<n;k++)
            	tmp.x[i][j]=(tmp.x[i][j]+a.x[i][k]*b.x[k][j]%mod)%mod;
    return tmp;
}
Matrix Mksm(Matrix a,LL b){
    Matrix ans;
    for(int i=0;i<n;i++)
        ans.x[i][i]=1;
    while(b){
        if(b&1)
            ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
}
int main(){
    LL k;
    Matrix a;
    cin>>n>>k;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            cin>>a.x[i][j];
    Matrix b=Mksm(a,k);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cout<<b.x[i][j]<<' ';
        }cout<<endl;
    }
    return 0;
}

矩阵优化dp

练习题单
P1939
在这里插入图片描述
P3758
在这里插入图片描述

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值