输入:
共两行
第一行 N ( 1<=N<=100 ),代表矩阵个数。
第二行有 N+1 个数,分别为 A1 、 A2 ...... An+1 ( 1<=Ak<=2000 ), Ak 和 Ak+1 代表第 k 个矩阵是个 Ak X Ak+1 形的。
输出:
共两行
第一行 M ,为最优代价。注:测试用例中 M 值保证小于 2^31
第二行为最优顺序。如 (A1((A2A3)A4)) ,最外层也加括号。
注意:测试用例已经保证了输出结果唯一,所以没有AAA的情况.
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
#include<iostream>
#include<cstdlib>
#define N 105
using namespace std;
int v[N][N]; //v[i][i]储存矩阵链从i到j的最小乘法次数
int c[N][N]; //c[i][j]储存矩阵链从i到j的最佳分割位置
int a[N]; //矩阵链
int n; //矩阵个数
void minproduct() //自底向上更新最小乘法次数和断点
{
for(int i=1;i<=n;i++) v[i][i]=0; //单个矩阵最小乘法次数为0
for(int lh=2;lh<=n;++lh) //计算长为lh的所有矩阵子链的最小乘法次数,lh递增
{
for(int st=1;st<=n-lh+1;++st)
{
int ed=st+lh-1; //此时取到的矩阵链子为[st,ed]
v[st][ed]=v[st+1][ed]+a[st-1]*a[st]*a[ed];
c[st][ed]=st;
for(int ct=st+1;ct<ed;++ct)
{
int pt=v[st][ct]+v[ct+1][ed]+a[st-1]*a[ct]*a[ed];
if(pt<v[st][ed]) //更新乘法次数和断点
{
v[st][ed]=pt;
c[st][ed]=ct;
}
}
}
}
}
void zprint(int s,int e)
{
if(s==e) cout<<'A'<<s;
else
{
cout<<'(';
zprint(s,c[s][e]);
zprint(c[s][e]+1,e);
cout<<')';
}
}
int main(){
cin>>n;
for(int i=0;i<=n;++i) cin>>a[i];
if(n>1)
{
minproduct();
cout<<v[1][n]<<endl;
zprint(1,n);
cout<<endl;
}
else //特判
{
cout<<0<<endl;
cout<<"(A1)"<<endl;
}
return 0;
}