题意:定义如下规则序列(字符串):
空序列是规则序列;
如果S是规则序列,那么(S)和[S]也是规则序列;
如果A和B都是规则序列,那么AB也是规则序列。
例如,下面的字符串都是规则序列:
(), [], (()), ([]), ()[], ()[()]
这几个则不是规则序列:
(, [, ], )(, ([()
现在,给出一些由‘(’,‘)’,‘[’,‘]’构成的序列,请添加尽量少的括号,得到一个规则序列。
思路:
黑书上的题目。经典dp
f[i][j]表示i..j这一段匹配完所需要添加的最少字母数
方程:f[i][j] = min(f[i][k] + f[k+1][j]) ( S[I] != S[J])
f[i][j] = min(f[i][k] + f[k+1][j] , f[i+1][j-1]); (S[I] == S[J])
其中, i <k <j
边界: f[i][i] = 1;
1 /* 2 State:Accepted 3 Time:2013.3.1 4 */ 5 6 #include <iostream> 7 #include <cstdlib> 8 #include <string> 9 #include <cstdio> 10 #include <algorithm> 11 #include <cmath> 12 #include <algorithm> 13 #include <vector> 14 #include <set> 15 #include <cstring> 16 #define Inf 100000; 17 using namespace std; 18 char s[200] ,s1[200]; 19 int n , f[200][200] ,map[200][200]; 20 21 void init(){ 22 scanf("%s",&s1); 23 for (int i = 0; i < strlen(s1) ; ++i) 24 s[i + 1] = s1[i];; 25 n = strlen(s1); 26 } 27 28 bool check(char word1, char word2){ 29 if (word1 == '(' && word2 == ')') return true; 30 if (word1 == '[' && word2 == ']') return true; 31 return false; 32 } 33 34 void dp(){ 35 int j ,temp; 36 for (int i = 1; i <= n; ++i) 37 for (int j = i; j <= n; ++j) 38 f[i][j] = Inf; 39 for (int i = 1; i <= n ; ++i ) 40 f[i][i] = 1; 41 42 for (int l = 2; l <= n; ++ l) 43 for (int i = 1; i <= n - l + 1; ++i){ 44 j = i + l -1; 45 if (check(s[i],s[j])) f[i][j] = min(f[i][j] , f[i + 1][j - 1] ); 46 for (int k = 1; k < l; ++k){ 47 temp = f[i][i + k -1] + f[i + k][j]; 48 if (temp < f[i][j]) { 49 f[i][j] = temp; 50 map[i][j] = i + k -1; 51 } 52 } 53 54 } 55 } 56 57 void print(int l , int r){ 58 if (l > r) return; 59 if (l == r){ 60 if (s[l] == '[' || s[l] == ']') 61 printf("[]"); 62 else printf("()"); 63 return; 64 } 65 if (map[l][r] == 0){ 66 printf("%c",s[l]); 67 print(l + 1 ,r - 1); 68 printf("%c",s[r]); 69 } else { 70 print(l ,map[l][r]); 71 print(map[l][r] + 1 , r); 72 73 } 74 75 } 76 77 int main(){ 78 freopen("poj1141.in","r",stdin); 79 freopen("poj1141.out","w",stdout); 80 init(); 81 dp(); 82 print(1 , n); 83 printf("\n"); 84 fclose(stdin); fclose(stdout); 85 }