矩阵连乘
#include<iostream>
#include<iomanip>
#include<vector>
#include<array>
#include<algorithm>
using namespace std;
class MatrixChain
{
public:
MatrixChain()
{
cin >> n;
p.assign(n + 1, -1);
vector<int> item1(1, -1);
m.push_back(item1);
s.push_back(item1);
for (int i = 1; i <= n; i++)
{
vector<int> item2(n+1 , -1);
m.push_back(item2);
s.push_back(item2);
}
for (int i = 0; i <= n; i++)
{
int n1;
cin >> n1;
p[i] = n1;
}
}
//动态规划的自底向上写法:
void BestChain()
{
for (int i = 1; i <= n; i++)
{
m[i][i] = 0;//初始长度的为1的矩阵链的连乘次数
s[i][i] = 0;
}
//自底向上计算长度大于2的矩阵链的连乘次数
for (int len = 2; len <= n; len++)//len递增
{
for (int k = 1; k <= n - len+1; k++)//扫描所有长度为len的矩阵链
{
int minm = 1000000;
int l = k + len - 1;
for (int j = k; j < l; j++)//在长度为len的矩阵链某处断开,在所有可能情况中找最小值
{
int temp = m[k][j] + m[j + 1][l] + p[k-1] * p[j] * p[l];
if (temp < minm)
{
minm = temp;
m[k][l] = temp;
s[k][l] = j;
}
}
}
}
}
//动态规划的递归写法:(不带备忘录)
void RecurMatrixChain(int i , int j)
{
if (i == j)
{
m[i][j] = 0;
s[i][j] = 0;
}
else
{
int minm = 10000000;
for (int k = i; k < j; k++)
{
//int minm = 10000000;, 不能写在这
RecurMatrixChain(i , k);
RecurMatrixChain(k + 1, j);
int temp = m[i][k] + m[k+1][j] + p[i-1] * p[k] * p[j];
if (temp < minm)
{
minm = temp;
m[i][j] = temp;
s[i][j] = k;
}
}
}
}
void TraceBack(int i , int j )//求解矩阵链A[i:j]的最佳加括号方式
{
if (j == i)
{
cout << "A" << i;
}
else
{
cout << "( ";
TraceBack(i, s[i][j]);
cout << " * ";
TraceBack(s[i][j] + 1, j);
cout << " )";
}
}
void print()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cout << setw(6) << m[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cout << setw(6) << s[i][j] << " ";
}
cout << endl;
}
TraceBack(1, n);
cout << endl;
}
public:
int n;
vector<vector<int> > m;//最少数乘次数
vector<int> p;//矩阵A[i] : row = p[i-1] , column = p[i]
vector<vector<int> > s;//记录矩阵A[i:j]的最佳断裂处
};
MatrixChain MC;
int main()
{
//MC.BestChain();
MC.RecurMatrixChain(1, MC.n);
MC.print();
return 0;
}