对于4个矩阵的乘法:
A * B * C * D
20*2 2*30 30*12 12*8
由于矩阵的乘法无关紧要,对上述的乘法可以产生5种不同的顺序,每一种顺序的乘法次数如下:
A(B(CD)):3680
(AB)(CD):8880
A((BC)D):1232
((AB)C)D:10320
(A(BC))D:3120
设m[i][j]=矩阵i到j所需要的最小乘法次数,d[i-1]*d[i]是第i个矩阵的维度
对于6个矩阵相乘,可以一下因式分解:
A1(A2A3A4A5A6)
(A1A2)(A3A4A5A6)
(A1A2A3)(A4A5A6)
(A1A2A3A4)(A5A6)
(A1A2A3A4A5)A6
得到递推方程:
分析该算法复杂度:
step是间隔
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
int d[1010];//矩阵维数,矩阵i的维数为d[i]*d[i+1]
int m[1010][1010];
int p[1010][1010];
void print(int l,int r)
{
if(l==r)
cout<<"A"<<l;
else
{
cout<<"(";
print(l,p[l][r]);
print(p[l][r]+1,r);
cout<<")";
}
}
int main()
{
int n;
cin>>n;//矩阵个数
cin>>d[1]>>d[2];
for(int i=2;i<=n;i++)
{
int t;
cin>>t>>d[i+1];
}
for(int i=1;i<=n;i++)
m[i][i]=0;
for(int step=1;step<=n-1;step++)
{
for(int i=1;i<=n-step;i++)
{
int j=i+step;
int minx=inf;
for(int k=i;k<=j-1;k++)
{
if(minx>(m[i][k]+m[k+1][j]+d[i]*d[k+1]*d[j+1]))
{
minx=m[i][k]+m[k+1][j]+d[i]*d[k+1]*d[j+1];
p[i][j]=k;
}
}
m[i][j]=minx;
}
}
cout<<m[1][n]<<endl;//最少乘法次数
print(1,n);//输出相乘顺序
return 0;
}
证明:
由公式:
...
将上式相加可得:
化简可得结果