最优矩阵链乘法
嘿嘿嘿我又来了
这次是最优矩阵链的乘法题
多个矩阵在连续相乘时会因为做乘的顺序而导致做乘的次数不一样,使用最优的矩阵链乘法会让计算速度大大加快。
如图,ABCD四个矩阵采用不同的次序相乘(根据结合律,得到的答案是一样的),最终的相乘次数差别非常大。所以我们需要找到一种算法找到算最少的次数,以节约时间。于是请出我们的主角----最优矩阵链乘法
上图,最少链乘次数的核心代码。
如图代码中的 p数组 代表矩阵的维度,因为给出的矩阵可以链乘,所以满足前行等后列(前面一行的元素个数一列的元素个数),所以便可以将p数组大小减半来存储,特别注意最后一个必须多开一位数组。
上代码
#include<cstdio>
using namespace std;
const int Maxn=10005;
int n,x,ax,m[Maxn][Maxn],s,v[Maxn][Maxn];
struct xy
{
int x,y;
} a[Maxn];
int work(int a,int b,int k)
{
if(a==b)
return 0;//a、b重合
if(a+1==b)
return m[a][b];//a、b相邻,不能继续分割
printf("%d ",k);
return m[a][b]+work(a,k,v[a][k])+work(k+1,b,v[k+1][b]);
}
int main()
{
freopen("最优矩阵链乘法.in","r",stdin);
freopen("最优矩阵链乘法.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].x,&a[i].y);
}
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++{
ax=0x3f3f3f3f;
for(int k=i;k<j;k++){
x=m[i][k]+m[k+1][j]+a[i].x*a[k].y*a[j].y;//状态转移方程
if(x<ax){
ax=x;
s=k;
}
}
m[i][j]=ax; v[i][j]=s;//记录切割点
}
printf("\n%d",work(1,n,v[1][n]));
return 0;
}