#include<iostream>
using namespace std;
//无论括号怎么分这些连续相乘的矩阵,最后括号都可以归结到只有两对括号,把整个连乘的矩阵分成两部分
// / 0 i==j
//m[i][j] =
// \ min{ m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j] } i<j, i<=k<j
//递归计算矩阵连乘
int liancheng(int i, int j, int *p, int **s) {
if (i == j)
return 0;
int MIN = liancheng(i, i, p, s) + liancheng(i + 1, j, p, s) + p[i - 1] * p[i] * p[j];
s[i][j] = i;
for (int k = i+1; k < j; k++) {
int rlt = liancheng(i, k, p, s) + liancheng(k+1, j, p, s) + p[i-1]*p[k]*p[j];
if(rlt < MIN) {
MIN = rlt;
s[i][j] = k;
}
}
return MIN;
}
int MatrixChain(int *p, int n, int **m, int **s) {
for (int i = 1; i <= n; i++)
m[i][i] = 0; //单个矩阵,计算次数为0
for (int r = 2; r <= n; r++) { //代表几个矩阵连乘
for (int i = 1; i <= n - r + 1; i++) { //i<=n-r+1是怎么得来的? i+r-1<=n
int j = i + r - 1;//r个矩阵相乘,最后一个矩阵的坐标为j
m[i][j] = m[i][i] + m[i + 1][j] + p[i - 1]*p[i]*p[j]; //把第一种m[i][j]的值当成是目前最小的,i也就是第一次k的位置
s[i][j] = i;
//为了求m[i][j]的所有情况中的最小值
for (int k = i + 1; k < j; k++) { //因为上面已经计算了k=i的情况,所以继续往下计算的话,就计算k=i+1,这个地方的k一定是小于j的,不能等于j
int temp = m[i][k] + m[k + 1][j] + p[i - 1]*p[k]*p[j];
if (temp < m[i][j]) {
m[i][j] = temp;
s[i][j] = k;
}
}
}
}
return m[1][n];
}
//求最优解,求出加括号的位置
void TraceBack(int i, int j, int **s)
{
if(i == j) return;
cout<<"a"<<i<<"~a"<<j<<" 把a"<<i<<"到a"<<s[i][j]<<"括起来, 把a"<<s[i][j]+1<<"到a"<<j<<"括起来"<<endl;
TraceBack(i, s[i][j], s);
TraceBack(s[i][j]+1, j, s);
}
//打印s数组,记录每个位置加括号的位置
void PrintS(int **s)
{
for(int i=1; i<=6; i++) {
for(int j=1; j<=6; j++) {
cout<<s[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
//6个矩阵连乘
int p[7] = { 30, 35, 15, 5, 10, 20, 25 };//用来存放每个矩阵的行和列数,第一个矩阵的行列为p[0][1], 第二个为p[1][2],第三
//个为p[2][3],依此类推
int **m; //传递二级指针的时候,这样做,直接int m[][],无法把m当作二级指针参数传进去
m = (int **)new int[7];
for (int i = 0; i < 7; i++) {
m[i] = (int *)new int[7];
}
int **s;
s = (int **)new int[7];
for(int i=0; i<7; i++)
s[i] = (int *)new int[7];
cout << "递归结果: " << liancheng(1, 6, p, s) << endl;
TraceBack(1, 6, s);
for(int i=1; i<=6; i++) //清空s数组
for(int j=1; j<=6; j++)
s[i][j] = 0;
cout << "动态规划结果: "<<MatrixChain(p, 6, m, s) << endl;
TraceBack(1, 6, s);
return 0;
}
动态规划--矩阵连乘
最新推荐文章于 2021-05-16 02:01:57 发布