【学习笔记】基础算法——矩阵乘法 & 矩阵快速幂
矩阵乘法
很水,只要按着题意模拟就行。
记得搞清定义。如果 \(A\) 矩阵是 \(n_1 \times m_1\) 的,\(B\) 矩阵是 \(n_2 \times m_2\) 的,那么必须在满足 \(m_1 = n_2\) 的情况下,两个矩阵才能做乘法。
具体的,是 \(A\) 的每一行的每个项依次与 \(B\) 的每一列的每个项做乘法,然后全部加起来,放进最终乘积 \(C\) 的那一行那一列。
所以就像我说的,\(C\) 最终是一个 \(n_1 \times m_2\) 的矩阵。
例题直接模拟即可。
粘上代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 105 ;
int n,m,k,a[N][N],b[N][N],c[N][N];
int main(){
cin>>n>>m>>k;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j];
for(int i=1;i<=m;i++)for(int j=1;j<=k;j++)cin>>b[i][j];
for(int i=1;i<=n;i++)for(int j=1;j<=k;j++)
for(int o=1;o<=m;o++)c[i][j]+=a[i][o]*b[o][j];
for(int i=1;i<=n;i++){
for(int j=1;j<=k;j++)cout<<c[i][j]<<" ";
cout<<"\n";
}
return 0;
}
矩阵快速幂
首先一个前置知识:矩阵乘法没有交换律(这点很重要!),但是有结合律,因此它才能进行快速幂!要不然怎么快速幂呢。
但是注意好了,快速幂的时候注意乘法的先后顺序!因为它没有交换律。
矩阵快速幂的代码与正常的快速幂极为相似,因为我们可以用结构体存储矩阵,然后重定义结构体的 * 运算,套上那啥模拟的矩阵乘法就行。这样我们写快速幂的时候就可以直接使用 * 了。
代码不贴了,就多了个快速幂而已。
楼梯问题
简单版本
这个其实上就是斐波那契数列,对吧。一眼就能看出来。
然后就是重点!我们的初始矩阵 & 转移矩阵是什么?
我们经过一系列推导,可以推出以下转移矩阵:
\begin{bmatrix}
1 & 1 \\
1 & 0
\end{bmatrix}
初始矩阵?当然是——
\begin{bmatrix}
\ 1 & 1 \
\end{bmatrix}
那么直接转移就行啦!
复杂版本
一样的。记着转移矩阵的推法!
可以先套上 \(m=2\) 的,试着推一推 \(m=3\) 的,进而知道 \(m=4\) 的,找出规律即可。当然有保险的推法更好啦,上述方案是为刚学矩阵快速幂的萌新准备的qwq
完整代码不贴啦!就贴一个一开始初始化转移矩阵 & 初始矩阵的代码吧。
for(int i=1;i<=m;i++)ans[i][i]=1,a[i][m]=1,a[i+1][i]=1;
nsdd,\(ans\) 是初始矩阵,\(a\) 是转移矩阵啦。
思考
矩阵快速幂这个东西,一般的用途就是,有一个递推式,但是你又不能直接递推去做这件事(时间复杂度炸了之类的),那么我们就会考虑用矩阵快速幂来加速递推。在图论题中,也存在直接用存图的邻接矩阵作为转移矩阵的,为的就是解决图论上的问题。当然一般需要把这个转移矩阵进行一系列的完善。当然不排除有水题。然后也有用矩阵快速幂优化 DP 的!毕竟 DP 也是一个递推式嘛。
那么一般看到以下几个关键信息就要联想到矩阵快速幂是否可做:
- 存在递推式
- 时间/空间复杂度会爆炸,无法直接递推
- DP 的递推式优化
- 图论题并且转移比较单一
- 使用邻接矩阵存图
很多时候看到递推式并且会爆炸的,一定一定要去看看矩阵快速幂是否可行!!!
总结
矩阵快速幂是个好东西。
把上面那句话划掉干啥!矩阵快速幂确实是个好东西啊。
矩阵快速幂解题的关键就在于:初始矩阵,递推矩阵!可能有时候后面还会让你乘一些东西。
记好了,矩阵有结合律,但是没有交换律!快速幂的时候一定记住,顺序别搞错了!

浙公网安备 33010602011771号