矩阵连乘问题, 需要注意的是 () 的输出问题
现放出用递归写的一个RE代码, 递归这里会暴栈:
#include <stdio.h> #include <iostream> #include <string.h> using namespace std; #define MIN(A,B) (A<B?A:B) int path[15][15]; int d[15][15]; int a[15][2]; int dp(int s, int e) { int i, j; int min, t, tp; min = 9999999; if(s >= e) return d[s][e] = 0; if(s+1 == e) return d[s][e] = a[s][0]*a[s][1]*a[e][1]; if(d[s][e]) return d[s][e]; for(i = s; i < e; i++) { tp = dp(s, i) + dp(i+1, e) + a[s][0]*a[s][1]*a[e][1]; if(tp < min) { min = tp; path[s][e] = i; } } d[s][e] = tp; return d[s][e]; } void print_path(int s, int e) { if(s == e) { printf("A%d", s); return; } if(s+1 == e) { printf("(A%d x A%d)", s, e); return; } printf("("); print_path(s, path[s][e]); printf("x"); print_path(path[s][e]+1, e); printf(")"); } int main() { int n; int cse = 1; while(scanf("%d", &n) != EOF) { int i, j; memset(d, 0, sizeof(d)); memset(path, 0, sizeof(path)); for(i = 1; i <= n; i++) { scanf("%d%d", &a[i][0], &a[i][1]); } dp(1, n); printf("Case %d: ", cse++); print_path(1, n); printf("\n"); } return 0; }
非递归代码:
#include<stdio.h> #include<string.h> #define MAXD 20 #define INF 1000000000 int N, left[MAXD], right[MAXD], f[MAXD][MAXD], p[MAXD][MAXD]; int init() { int i; scanf("%d", &N); if(!N) return 0; for(i = 0; i < N; i ++) scanf("%d%d", &left[i], &right[i]); } void printpath(int a, int b) { if(a == b) { printf("A%d", a + 1); return ; } printf("("); printpath(a, p[a][b]); printf(" x "); printpath(p[a][b] + 1, b); printf(")"); } void solve() { int i, j, k, temp; for(i = 0; i < N; i ++) for(j = i; j < N; j ++) { if(i == j) f[i][j] = 0; else f[i][j] = INF; } for(k = 1; k < N; k ++) for(i = 0; i + k < N; i ++) for(j = i; j < i + k; j ++) { temp = f[i][j] + f[j + 1][i + k] + left[i] * right[j] * right[i + k]; if(temp < f[i][i + k]) { f[i][i + k] = temp; p[i][i + k] = j; } } printpath(0, N - 1); printf("\n"); } int main() { int t = 0; while(init()) { printf("Case %d: ", ++ t); solve(); } return 0; }