黑书p113上的题。
我的思路:
f[i][j]:i-j的最短规则序列长度
f[i][j] = f[i][j - 1] + 2;
当 s[j] == ')' && s[k] == '(' || s[j] == ']' && s[k] == '[' 时
f[i][j] <?= f[i][k - 1] + f[k + 1][j];
/** * Problem:POJ1141 * Author:Shun Yao * Time:2013.5.19 * Result:Accepted * Memo:DP */ #include <cstring> #include <cstdlib> #include <cstdio> using namespace std; long n, f[105][105], g[105][105]; char s[105]; void print_the_solution(long i, long j) { if (i > j) return; if (!g[i][j]) { print_the_solution(i, j - 1); if (s[j] == '(' || s[j] == ')') printf("()"); else printf("[]"); } else { print_the_solution(i, g[i][j] - 1); printf("%c", s[g[i][j]]); print_the_solution(g[i][j] + 1, j - 1); printf("%c", s[j]); } } int main() { static long i, j, k, l, tmp; freopen("poj1141.in", "r", stdin); freopen("poj1141.out", "w", stdout); scanf("%s", s + 1); n = strlen(s + 1); for (i = 1; i <= n; ++i) { memset(f[i], 0, sizeof f[i]); memset(g[i], 0, sizeof g[i]); f[i][i] = 2; } for (l = 2; l <= n; ++l) for (i = 1; i <= n - l + 1; ++i) { j = i + l - 1; f[i][j] = f[i][j - 1]; if (s[j] == ']') { for (k = i; k < j; ++k) if (s[k] == '[' && f[i][j] > (tmp = f[i][k - 1] + f[k + 1][j - 1])) { f[i][j] = tmp; g[i][j] = k; } } else if (s[j] == ')') { for (k = i; k < j; ++k) if (s[k] == '(' && f[i][j] > (tmp = f[i][k - 1] + f[k + 1][j - 1])) { f[i][j] = tmp; g[i][j] = k; } } f[i][j] += 2; } print_the_solution(1, n); putchar('\n'); fclose(stdin); fclose(stdout); return 0; }