矩阵乘法问题,区间dp。动规方程为:f[i][j] = min{ f[i][k] + f[k+1][j] + p[i] * q[k] * q[j] } (k>=i && k < j)。其中f[i][j] 表示的是区间[i ,j ]内的最优值。p[i]表示矩阵i的行,q[i]表示矩阵i的列。递推的时候采用区间j-i的长度来一次递推。这样比较容易计算以及状态的转移。代码如下:
/*
ID; csuanchen
PROG: 348 Optimal Array Multiplication Sequence
LANG: C++
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std ;
#define INF 100000000
const int maxn = 15 ;
int martix[maxn][2] ;
int dp[maxn][maxn] ;
int fl[maxn][maxn] ;
int n ;
void print(int left , int right) ;
int main()
{
int test ;
test = 0 ;
while(cin>>n && n)
{
int i ;
int j ;
int len ;
int k ;
memset(martix , 0 , sizeof(martix)) ;
memset(dp , 0 , sizeof(dp)) ;
memset(fl , 0 , sizeof(fl)) ;
for(i = 0 ; i < n ; i ++)
cin>>martix[i][0]>>martix[i][1] ;
for(len = 1 ; len <= n ; len ++)
{
for(i = 0 ; i <= n - len ; i ++)
{
j = i + len - 1 ;
dp[i][j] = INF ;
if(i == j )
dp[i][j] = 0 ;
for(k = i ; k < j ; k ++)
{
int temp = dp[i][k] + dp[k + 1][j] + martix[i][0] * martix[k][1] * martix[j][1] ;
if(dp[i][j] > temp)
{
dp[i][j] = temp ;
fl[i][j] = k ;
}
}
}
}
cout<<"Case "<<++test<<": ";
print(0 , n - 1) ;
cout<<endl ;
}
return 0 ;
}
void print(int left , int right)
{
if(left!=right)
{
cout<<"(" ;
print(left , fl[left][right]) ;
cout<<" x " ;
print(fl[left][right] + 1 , right) ;
cout<<")" ;
}
else if( left == right && left != n - 1 )
cout<<"A"<<left + 1;
else if( left == right && left == n - 1 )
cout<<"A"<<right + 1 ;
}