最优矩阵链乘问题。经典dp问题。
我的解题代码如下,其中dp[i][j]表示计算从第i个矩阵到第j个矩阵的矩阵链的乘积所需的最少乘法次数,dpi[i][j]表示计算从第i到第j个矩阵乘积所做的最后一次乘法在第dpi[i][j]个矩阵之后的位置。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define maxn 10
const int INF = 0x7fffffff;
int Row[maxn], Col[maxn];
int dp[maxn][maxn];
int dpi[maxn][maxn];
int f(int s, int t)
{
if(dp[s][t]!=-1) return dp[s][t];
dpi[s][t] = s;
if(s==t) return dp[s][t] = 0;
int min = INF, tmp;
for(int i=s; i<t; i++)
{
tmp = f(s,i)+f(i+1,t)+Row[s]*Col[i]*Col[t];
if(min>tmp) { min = tmp; dpi[s][t] = i; }
}
return dp[s][t] = min;
}
void print(int s, int t)
{
if(s>t) return;
if(s==t) { printf("A%d",s+1); return ;}
printf("(");
print(s,dpi[s][t]);
printf(" x ");
print(dpi[s][t]+1,t);
printf(")");
return;
}
int main()
{
int N, Case = 0;
while(scanf("%d",&N) && N)
{
for(int i=0; i<N; i++) scanf("%d %d",&Row[i],&Col[i]);
memset(dp,-1,sizeof(dp));
printf("Case %d: ",++Case);
f(0,N-1);
print(0,N-1);
printf("\n");
}
return 0;
}