题目:n个矩阵连乘,不满足交换律,但是满足结合律,通过不同的加括号方式,会使得需要的乘法次数不同。用动态规划方法计算,找出最优加括号方式,使总的乘法次数最少。
代码:
#include
using namespace std;
int p[100];
int m[100][100];
int s[100][100];
int MatrixChain(int n) {
cout << "请输入第一个矩阵的行数:";
cin >> p[0];
for (int q = 1; q <= n; q++) {
cout << "请输入第" << q << "个矩阵的列数:";
cin >> p[q];
}
cout << "你输入的矩阵为:" << endl;
for (int i = 1; i <= n; i++) {
cout << "A" << i << "[" << p[i - 1] << "]" << "[" << p[i] << "]" << "\n";
}
for (int i = 1; i <= n; i++) {
m[i][i] = 0;
}
for (int r = 2; r <= n; r++) { //r为子链长度,由2到n
for (int i = 1; i <= n - r + 1; i++) { //i最大到n-子链长度+1
int j = i + r - 1; //j则为i+子链长度-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;
}
}
}
}
return 0;
}
int Mcout(int n) {
cout << "矩阵的最优乘法次数为:" << endl;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (j > i) {
cout << m[i][j] << " ";
}
else
{
cout << "0" << " ";
}
}
cout << endl;
}
cout << "矩阵的最佳分割点位置为:" << endl;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (j > i) {
cout << s[i][j] << " ";
}
else
{
cout << "0" << " ";
}
}
cout << endl;
}
return 0;
}
int TraceBack(int i, int j) {
//cout << i << ' ' << j << endl;
if (i == j) {
cout << "A" << i;
}
else {
cout << "(";
TraceBack(i, s[i][j]);
TraceBack(s[i][j] + 1, j);
cout << ")";
}
return 0;
}
int main()
{
int n;
cout << "请输入矩阵个数:";
cin >> n;
MatrixChain(n);
Mcout(n);
TraceBack(1, n);
}
结果截图:
实验结果分析:
矩阵连乘时,四个矩阵中,矩阵不能进行交换,且上一个矩阵的列数一定等于下一个矩阵的行数才能进行矩阵的乘法,所以只需要记录第一个矩阵的行数以及每个矩阵的列数,就可知每个矩阵的行列数。如图结果所示:在四个矩阵中,第一个矩阵为3×4,第二个矩阵为4×5,第三个矩阵为5×2,第四个矩阵为2×6,通过动态规划,最终得到的最少乘法次数为100,对应的括号是:(A1(A2A3))A4
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)