问题描述:给定n个矩阵{A1,A2,A3.....An},其中Ai与Ai+1是可乘的,i=1,2,3....n-1,考察这n个矩阵的连乘积
若A是一个 p* q 矩阵,B是一个 q* r 矩阵,则其乘积C = A* B 是一个 p* r 矩阵,主要运算量是三重循环,共需要p* q* r次数乘。
动态规划核心公式 m[i][j] = min{m[i][k]+m[k+1][j]+Pi-1*PkPj } i<j i<=k<j
许多子问题被重复计算多次,这是该问题可用动态规划求解的一显著特征
void MatrixChain(vector<int> &p,int n,vector<vector<int> > &m,vector<vector<int> > &s)
{
for(int i =1;i<=n;i++)
{
m[i][i] = 0;
}
for(int r = 2;r<=n;r++)//r为 i 和 j之间的距离!!!
{
for(int i = 1;i<=n-r+1;i++)//这个循环条件要注意哦!,也就是 j<n 啦
{
int j = i+r-1;
m[i][j] = m[i-1][j] + p[i-1]*p[i]*p[j];
s[i][j] = i;
for(int k = i+1;k<j;k++)
{
int t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
if(t<m[i][j])
{
m[i][j] = t;
s[i][j] = k;//中断点记录下来了
}
}
}
}
}
struct symbol
{
int leftParent = 0, rightParent = 0;
};
//获取符号位置
void getExpression(int start, int end, vector<symbol> &symbols, vector<vector<int>> &s)
{
if (start == end) {
return;
}
else
{
symbols[start].leftParent++;
symbols[end + 1].rightParent++;
}
if (start + 1 == end) {
return;
}
int posi = s[start][end];
getExpression(start, posi, symbols,form);
getExpression(posi + 1, end, symbols,form);
}
//输出表达式
void Traceback(vector<symbol> symbols, vector<vector<cell>> &s,int n) {
getExpression(0, n - 1, symbols, s);
for (int i = 0; i < n; i++)
{
int l = symbols[i].leftParent, r = symbols[i].rightParent;
while (r--)
{
cout << ")";
}
while (l--)
{
cout << "(";
}
cout << " " << 'A' << i+1 << " ";
}
int r = symbols[n].rightParent;
while (r--)
{
cout << ")";
}
}