#include<iostream>
#include<vector>
#include<iterator>
#include<algorithm>
using namespace std;
/*
*矩阵连乘(备忘录方法:自顶向下递归)
*/
vector<vector<int> > m;//m[i][j]表示矩阵Ai连乘到Aj的最少运算次数
vector<vector<int> > s;//s[i][j]记录矩阵Ai和矩阵Aj之间的分割点
//计算该连乘式子的最佳结合方式
int MatrixChain(vector<int>& p,int beg, int end)
{
if(m[beg][end]>0)
{
return m[beg][end];
}
if(beg==end)
return 0;
int u = MatrixChain(p,beg,beg) +MatrixChain(p,beg+1,end)+p[beg-1]*p[beg]*p[end];
s[beg][end] = beg;
for (int K = beg+1; K <end ; K++)
{
int t = MatrixChain(p,beg,K) + MatrixChain(p,K+1,end) + p[beg-1]*p[K]*p[end]; //递归
if (t<u)
{
u = t; //从k点处断开,分别求得每次的数乘次数
s[beg][end] = K;//返回 t,k中较小的值,并记录断点处 k
}
}
m[beg][end] = u;
return u;
}
//输出该连乘式子的最佳结合方式
void PrintMatrixChain(int n,int m)
{
if(n==m) //只有一个矩阵,直接输出
{
cout<<"A"<<n;
return;
}
int k = s[n][m];
if(n==k)
PrintMatrixChain(n,k); //递归
else
{
cout<<"(";
PrintMatrixChain(n,k);
cout<<")";
}
if(k+1==m) //两个矩阵
PrintMatrixChain(k+1,m); //递归
else
{
cout<<"(";
PrintMatrixChain(k+1,m); //递归,从得到最优解的地方 s[][]处断开
cout<<")";
}
}
int main()
{
vector<int> vec; //创造一个空的容器 vec
copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(vec));
int n = vec.size()-1;//一共有n个矩阵相乘
m = vector<vector<int> >(n+1,vector<int>(n+1,0));//0行0列空余
s = vector<vector<int> >(n+1,vector<int>(n+1,0));//0行0列空余
//初始化m数组
for(int i = 0;i<=n;i++) m[i][i] = 0;
int u = MatrixChain(vec,1,n);
cout<<"最优解为计算"<<u<<"次乘法!"<<endl;
PrintMatrixChain(1,vec.size()-1);
return 0;
}
03-24
1825
05-16