题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=452
用dp[i][j] 记录一段序列,starts from index i, ends with index j,需要添加的char的个数。对于一段序列i~j,如果i, j 配对的话,那么dp[i][j]=dp[i+1][j-1].如果i, j不配对的话,那就需要对序列进行分割,dp[i][j]=dp[i][k]+dp[k+1][j],对k进行for loop找到最佳的k。但是当i, j配对时,并不代表dp[i+1][j-1]是最佳的结果,仍旧需要寻找最佳的k。代码如下:
1 #include <iostream> 2 #include <math.h> 3 #include <stdio.h> 4 #include <cstdio> 5 #include <algorithm> 6 #include <string.h> 7 #include <string> 8 #include <sstream> 9 #include <cstring> 10 #include <queue> 11 #include <vector> 12 #include <functional> 13 #include <cmath> 14 #include <set> 15 #define SCF(a) scanf("%d", &a) 16 #define IN(a) cin>>a 17 #define FOR(i, a, b) for(int i=a;i<b;i++) 18 #define Infinity 9999999 19 typedef long long Int; 20 using namespace std; 21 22 int path[105][105]; 23 char brackets[105]; 24 void sprint(int s, int e) 25 { 26 if (s > e) 27 return; 28 if (s == e) 29 { 30 if (brackets[s] == '(' || brackets[s] == ')') 31 printf("()"); 32 else 33 printf("[]"); 34 } 35 else 36 { 37 if (path[s][e] == -1) 38 { 39 printf("%c", brackets[s]); 40 sprint(s + 1, e - 1); 41 printf("%c", brackets[e]); 42 } 43 else 44 { 45 sprint(s, path[s][e]); 46 sprint(path[s][e] + 1, e); 47 } 48 } 49 } 50 51 int main() 52 { 53 int N; 54 SCF(N); 55 cin.get(); 56 int len = 0; 57 int dp[105][105]; 58 FOR(casenum, 0, N) 59 { 60 cin.get(); 61 cin.getline(brackets, 105); 62 len = 0; 63 for (len = 0; brackets[len] != '\0'; len++); 64 65 if (casenum) 66 printf("\n"); 67 if (len == 0) 68 { 69 printf("\n"); 70 continue; 71 } 72 FOR(i, 0, len) 73 { 74 FOR(j, 0, len) 75 dp[i][j] = 0; 76 } 77 FOR(i, 0, len) 78 dp[i][i] = 1; 79 int end = 0; 80 81 FOR(clen, 1, len) 82 { 83 FOR(start, 0, len - clen) 84 { 85 end = start + clen; 86 dp[start][end] = Infinity; 87 88 if ((brackets[start] == '(' && brackets[end] == ')') || (brackets[start] == '[' && brackets[end] == ']')) 89 { 90 dp[start][end] = dp[start + 1][end - 1]; 91 path[start][end] = -1; 92 } 93 94 for (int k = start; k < end; k++) 95 { 96 if (dp[start][end] > dp[start][k] + dp[k + 1][end]) 97 { 98 dp[start][end] = dp[start][k] + dp[k + 1][end]; 99 path[start][end] = k; 100 } 101 } 102 103 104 } 105 } 106 sprint(0, len - 1); 107 printf("\n"); 108 } 109 110 return 0; 111 }