UVA348 经典dp
dp题比较灵活主要是找到状态量和状态转移方程
这道题的状态转移方程为f(a, b) = min(f(a, i) + f(i+1, b) + x[a]*y[i]*y[b])
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int x[15], y[15];
int d[15][15], vis[15][15], sign[15][15]; //记录a,b间的i的数值;
int dp(int a, int b){
if(vis[a][b])
return d[a][b];
vis[a][b] = 1;
if(a == b)
return d[a][b] = 0;
sign[a][b] = a;
d[a][b] = 1 << 30; // 赋值int类型的最大值
for(int i = a; i < b; ++i){
int t = dp(a, i) + dp(i+1, b) + x[a]*y[i]*y[b];
if(t < d[a][b]){
d[a][b] = t;
sign[a][b] = i;
}
}
return d[a][b]; // d[a][b] 最少的矩阵链乘次数
}
void print(int a, int b){
if(a > b)
return ;
if(a == b)
printf("A%d", a+1);
else{
printf("(");
print(a, sign[a][b]);
printf(" x ");
print(sign[a][b]+1, b);
printf(")");
}
}
int main()
{
int n, cas = 0;
while(~scanf("%d", &n) && n){
for(int i = 0; i < n; ++i){
scanf("%d%d", x+i, y+i);
}
memset(d, 0, sizeof(d));
memset(vis, 0, sizeof(vis));
dp(0, n-1);
printf("Case %d: ", ++cas);
print(0, n-1);
printf("\n");
}
return 0;
}