动态规划之矩阵连乘问题

#include <iostream>
using namespace std;
 
/* 矩阵连乘思路:ABCD分别代表4个不同的矩阵,我可以(A)*(BCD) ,(AB)*(CD),(ABC)*(D),也就是取这三个最小值,对于其子问题也是一样的3个矩阵,2个矩阵。。。。。
所以用dp[i][j]表示合并矩阵从i到j需要付出的最小代价也就是最优值,从小例子可以看出想要得到当前阶段的最优值,需要先解决之前所有阶段的最优值,所以核心代码是:
for(int r=2;r< =n;r++)//意味不同阶段 
for(int i=1;i<=n-r+1;i++ )//同一阶段的不同状态,从中选出最优值 
{
int j=i+r-1;//右边界
dp [i][j]=dp[i+1][j]+p[i-1]*p[i]*p[j];/*p[i]:记录矩阵i的列数,p[i-1]是矩阵i-1的列数,同时也是i的行数 ,
这里对dp[i][j]的操作是先用了第一种分割,比如ABCD中用了第一种A(BCD)为了方便和后面的分割方法比较最优值,
for(int k=i+1;k<j;k++){
t=dp[i][k]+dp[k+!][j]+p[i-1]*p[k]*p[j];
if(dp[i][j]>t)
dp[i][j]=t;
}



测试用例:
A1:30*35 A2:35*15 A3:15*5 A4:5*10 A5:10*20 A6:20*25 
目标结果:15125 
*/
int p[7]={30,35,15,5,10,20,25};
int dp[7][7];
int s[7][7];
int Left[7];
int Right[7];
int DP(int n) {
int t;
for(int r=2;r<=n;r++)
for(int i=1;i<=n-r+1;i++ )
{
int j=i+r-1;
dp [i][j]=dp[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j]=i;
for(int k=i+1;k<j;k++){
t=dp[i][k]+dp[k+1][j]+p[i-1]*p[k]*p[j];
if(dp[i][j]>t)
{
dp[i][j]=t;
s[i][j]=k;
}
}


return dp[1][6];
}
void Solve(int start,int end){
if(start==end) return;
int solve=s[start][end];
Right[solve]++;
Left[solve]++;
Left[start]++;
Right[end]++;
Solve(start,solve);
Solve(solve+1,end);
}
void show(int start,int end){ 
Solve(start,end);
for(int i=1;i<=end;i++)
{
while(Left[i]--)
cout<<"( " ;
cout<<"A"<<i ;
while(Right[i]--)
cout<<" )" ; 
}

int main(int argc, char** argv) {
cout<<DP(6)<<endl;
show(1,6);
return 0;

}




猜你喜欢

转载自blog.csdn.net/LLXLQY/article/details/79343105