浅谈矩阵加速优化动态规划
浅谈矩阵加速优化动态规划
本文只适用于OI学习
矩阵乘法
给定两个矩阵
那么,
用数学公式表述那就是:
一般来说,
由于矩阵乘法满足分配率,结合律(但是不满足交换律!),所以我们可以通过矩阵快速幂的方法来加速
代码实现:
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
我们魔改一下:
int C[N][N];
memset(C,127,sizeof C); // inf
for(int k=1;k<=n;j++)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
C[i][j]=min(C[i][j],A[i][k]+A[k][j]);
}
memcpy(A,C,sizeof C);
之所以可以加
那么它代表的意义又是什么呢? 先放出例题
让我们做下列这个实验: 实验代码
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int A[1001][1001];
int C[1001][1001];
signed main()
{
freopen("data.in","r",stdin);
int n,m;
scanf("%d %d",&n,&m);
memset(A,50,sizeof A);
for(int i=1;i<=m;i++)
{
int a,b,c;
scanf("%d %d %d", &a,&b,&c);
A[a][b]=A[b][a]=c;
A[i][i]=0;
}
int tmp=1;// 看这里!!!!!!!!
while(tmp--)
{
memset(C,127 , sizeof C);
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
C[i][j]=min(C[i][j],A[i][k]+A[k][j]);
}
memcpy(A,C,sizeof C);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
if(A[i][j]<100)
printf("%d ",A[i][j]);
else
{
printf("X ");
}
printf("\n");
}
}
给出一条链:
输入的邻接矩阵
容易发现,当
下面是我记录的实验数据:
| tmp | 邻接矩阵第一行(也就是点1到各个点距离) |
|---|---|
| 1 | 0 1 2 X X X X X X X |
| 2 | 0 1 2 3 4 X X X X X |
| 3 | 0 1 2 3 4 5 6 7 8 X |
容易发现,
于是上边的例题就能通过矩阵快速幂轻松解决!