uva 348 Optimal Array Multiplication Sequence(区间dp)

题目连接:348 - Optimal Array Multiplication Sequence


题目大意:给出n个矩阵, 每个矩阵有它的行和列, 现在要计算这n个连续的矩阵的乘积, 要求找出计算量最小的方案, 每两个矩阵相乘的计算量为(a.l * a.r * b.r),然后生成一个a.l和b.r的矩阵。


解题思路:典型的区间dp, 只不过在每次找最优解之后要记录当前区间的最优分解点rec[a][b]。


#include <stdio.h>
#include <string.h>
const int N = 105;

struct state {
    int l;
    int r; 
}tmp[N];
int n, dp[N][N], rec[N][N];

void Init() {
    memset(dp, 0, sizeof(dp));
    memset(rec, 0, sizeof(rec));

    for (int i = 0; i < n; i++)
	scanf("%d%d", &tmp[i].l, &tmp[i].r);
}

int solve(int a, int b) {
    if (dp[a][b])   return dp[a][b];
    if (a == b)	return 0;
    if (a + 1 == b) return dp[a][b] = tmp[a].l * tmp[a].r * tmp[b].r;

    int now, Max = 1 << 30;
    for (int i = a; i < b; i++) {
	now = solve(a, i) + solve(i + 1, b) + tmp[a].l * tmp[i].r * tmp[b].r;
	if (now < Max) {
	    Max = now;
	    rec[a][b] = i;
	}
    }
    dp[a][b] = Max;
    return Max;
}

void print(int a, int b) {
    if (a == b)
	printf("A%d", a + 1);
    else if (a + 1 == b)
	printf("(A%d x A%d)", a + 1, b + 1);
    else {
	printf("(");
	print(a, rec[a][b]);
	printf(" x ");
	print(rec[a][b] + 1, b);
	printf(")");
    }
}

int main() {
    int cas = 1;
    while (scanf("%d", &n), n) {
	Init();
	solve(0, n - 1);
	printf("Case %d: ", cas++);
	print(0, n - 1);
	printf("\n");
    }
    return 0;
}


你可能感兴趣的:(uva 348 Optimal Array Multiplication Sequence(区间dp))