Brackets Sequence
Description Let us define a regular brackets sequence in the following way:
1. Empty sequence is a regular sequence. 2. If S is a regular sequence, then (S) and [S] are both regular sequences. 3. If A and B are regular sequences, then AB is a regular sequence. For example, all of the following sequences of characters are regular brackets sequences: (), [], (()), ([]), ()[], ()[()] And all of the following character sequences are not: (, [, ), )(, ([)], ([(] Some sequence of characters '(', ')', '[', and ']' is given. You are to find the shortest possible regular brackets sequence, that contains the given character sequence as a subsequence. Here, a string a1 a2 ... an is called a subsequence of the string b1 b2 ... bm, if there exist such indices 1 = i1 < i2 < ... < in = m, that aj = bij for all 1 = j = n. Input The input file contains at most 100 brackets (characters '(', ')', '[' and ']') that are situated on a single line without any other characters among them.
Output Write to the output file a single line that contains some regular brackets sequence that has the minimal possible length and contains the given sequence as a subsequence.
Sample Input ([(] Sample Output ()[()] 1 /*对于DP题目需要记录到底是怎样得到结果的,不一定了可以通过记录信息直接得到,可以选择数组记录其他有用信息,可以写递归来找出最后的答案。*/ 2 #define N 111 3 #include<iostream> 4 using namespace std; 5 #include<cstring> 6 #include<cstdio> 7 #define inf (1<<31)-1 8 int f[N][N],pos[N][N],lens; 9 char s[N]; 10 void print(int l,int r)/*输出序列的过程*/ 11 { 12 if(l<=r)/*一定要有这一句,否则对于相邻的‘()’,就会死循环了*/ 13 { 14 if(l==r)/*能到这一步,说明只能补上括号了*/ 15 { 16 if(s[l]=='('||s[l]==')') printf("()"); 17 if(s[l]=='['||s[l]==']') printf("[]"); 18 } 19 else 20 { 21 if(pos[l][r]==-1)/*说明该区间最左括号与最右匹配*/ 22 { 23 printf("%c",s[l]); 24 print(l+1,r-1);/**/ 25 printf("%c",s[r]); 26 } 27 else 28 { 29 print(l,pos[l][r]); 30 print(pos[l][r]+1,r); 31 } 32 } 33 } 34 } 35 int main() 36 { 37 // freopen("bracket.in","r",stdin); 38 // freopen("bracket.out","w",stdout); 39 scanf("%s",s+1); 40 lens=strlen(s+1); 41 for(int i=1;i<=lens;++i) 42 f[i][i]=1; 43 /* for(int i=lens-1;i>=1;--i) 44 for(int j=i+1;j<=lens;++j) 45 { 46 f[i][j]=inf; 47 if(((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']'))) 48 { 49 f[i][j]=f[i+1][j-1]; 50 pos[i][j]=-1; 51 } 52 53 for(int k=i;k<=j-1;++k) 54 { 55 if(f[i][j]>f[i][k]+f[k+1][j]) 56 { 57 f[i][j]=f[i][k]+f[k+1][j]; 58 pos[i][j]=k; 59 } 60 61 } 62 63 }这两种都是可以得出正确答案的,但是我建议使用下面的,对于区间DP,最外层循环最好枚举区间长度,内层枚举区间*/ 64 for(int k=1;k<lens;++k) 65 for(int i=1,j=i+k;j<=lens&&i<=lens;++j,++i) 66 { 67 f[i][j]=inf; 68 if((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']')) 69 { 70 f[i][j]=f[i+1][j-1]; 71 pos[i][j]=-1; 72 } 73 /*不要加else,因为即使当前区间的最左和最右匹配,也不一定比放弃他们匹配优*/ 74 for(int k=i;k<=j-1;++k) 75 { 76 if(f[i][j]>f[i][k]+f[k+1][j]) 77 { 78 f[i][j]=f[i][k]+f[k+1][j]; 79 pos[i][j]=k; 80 } 81 82 } 83 84 } 85 print(1,lens); 86 printf(" ");/*坑爹的POJ,没有这句,一直没对*/ 87 //fclose(stdin);fclose(stdout); 88 return 0; 89 } |