版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HackQ_sxj/article/details/80571910
问题描述: 利用动态规划方法,求解下面矩阵连乘A1A2A3A4所需的最少数乘次数,并给出最佳乘积序列,要求给出求解步骤,给出最优值数组和最佳断开位置数组。其中,pi-1 为矩阵Ai的行数,pi为矩阵Ai的列数,四个矩阵中各矩阵维数分别如下:
解题思想:计算A[i:j]矩阵的最小连乘,1<=i<=j<=n,所需要的最小数乘次数为m[i, j]。
当i=j时,A[i:j]=Ai,因此,m[i,i]=0,i=1,2,…,n。
当i<j时,若A[i:j]的最优次序在Ak和Ak+1间断开,则m[i, j] = min{m[i, k]+m[k+1, j]+pi-1pk[j}, i<=k<=j.
代码如下:
#include <iostream>
#include <stdlib.h>
using namespace std;
int MatrixChain(int *p, int n, int **m, int **s)
{
for(int i = 1; i < n; i++) m[i][i] = 0;
for(int r = 2; r <= n; r++)
for(int i = 1; i <= n-r+1; i++)
{
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;
}
}
}
return m[1][n];
}
void Traceback(int i, int j, int **s)
{
if (i == j)
{
cout << "A" << i;
return;
}
cout << "(";
Traceback(i, s[i][j], s);
Traceback(s[i][j] + 1, j, s);
cout << ")";
}
int main(){
int n = 4;
int p[5] = {10,100,5,50,10};
int **m = new int*[n+1];
int **s = new int*[n+1];
for (int i = 0; i < n+1; i++)
{
m[i] = new int[n+1];
s[i] = new int[n+1];
}
int x = MatrixChain(p, n, m, s);
cout<<"最小连乘数为:"<<x<<endl;
cout<<"最优解为:"<<endl;
Traceback(1, n, s);
for (int i = 0; i < n+1; i++)
{
delete[] m[i];
delete[] s[i];
}
delete[]m;
delete[]s;
return 0;
}
结果: