http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105116#problem/E
题意:添加最少的括号,让每个括号都能匹配并输出
分析:dp[i][j]表示第i个到第j个需要添加的最少的括号,pos[i][j] = k;表示i到j间第k个需要加括号;
如果str[i]和str[j]匹配,那么dp[i][j] = max(dp[i + 1][j - 1], dp[i][j]);
如果str[i]和str[j]不匹配,那么dp[i][j] = max(dp[i][j], dp[i][k]+dp[k + 1][j]); i<= k < j;之前想过k为什么不能等于j,
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 using namespace std; 6 const int MAX = 120; 7 const int INF = 0x3f3f3f3f; 8 int dp[MAX][MAX],pos[MAX][MAX]; 9 char str[MAX]; 10 int n; 11 void DP() 12 { 13 n = strlen(str); 14 15 memset(dp, 0, sizeof(dp)); 16 for(int i = 0; i < n; i++) 17 dp[i][i] = 1; 18 for(int p = 1; p < n; p++) 19 { 20 for(int i = 0; i < n; i++) 21 { 22 int j = i + p; 23 if(j >= n) 24 break; 25 dp[i][j] = INF; 26 if( (str[i] == '(' && str[j] == ')') || ( str[i] == '[' && str[j] == ']' ) ) 27 { 28 if(dp[i][j] > dp[i + 1][j - 1]) 29 dp[i][j] = dp[i + 1][j - 1]; 30 } 31 pos[i][j] = -1; 32 for(int k = i; k < j; k++) 33 { 34 int temp = dp[i][k] + dp[k + 1][j]; 35 if(temp < dp[i][j]) 36 { 37 dp[i][j] = temp; 38 pos[i][j] = k; 39 } 40 } 41 } 42 } 43 } 44 void Print(int beg, int End) 45 { 46 if(beg > End) 47 return; 48 if(beg == End) 49 { 50 if(str[beg] == '(' || str[beg] == ')') 51 printf("()"); 52 if(str[beg] == '[' || str[beg] == ']') 53 printf("[]"); 54 } 55 else 56 { 57 if(pos[beg][End] == -1) 58 { 59 printf("%c", str[beg]); 60 Print(beg + 1, End - 1); 61 printf("%c", str[End]); 62 } 63 else 64 { 65 Print(beg, pos[beg][End]); 66 Print(pos[beg][End] + 1, End); 67 } 68 } 69 } 70 int main() 71 { 72 int t; 73 scanf("%d", &t); 74 getchar(); 75 getchar(); 76 for(int i = 0; i < t; i++) 77 { 78 gets(str); 79 DP(); 80 Print(0, n - 1); 81 printf("\n"); 82 if(i < t - 1) 83 printf("\n"); 84 getchar(); 85 } 86 87 return 0; 88 }