[DP] UVA-1626 Brackets sequence
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
Input
The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.
The input file contains at most 100 brackets (characters ‘(’, ‘)’, ‘[’ and ‘]’) that are situated on a single line without any other characters among them.
Output
For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.
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
1
([(]
Sample Output
()[()]
題意:
定義如下序列為合法的括號序列:
1、空序列為合法序列
2、若S是合法序列,則(S), [S]也為合法序列
3、若A、B均為合法序列,則AB也為合法序列
題目給出一個括號序列,添加最少的(, ), [, ]使序列合法。
思路:本題是經典的區間DP,思想是不斷分割小區間,直到出現(S)或[S]時,狀態轉移到S,即從dp[i][j]轉移到dp[i + 1][j - 1]。
PS:該題的讀入和輸出很坑,需要註意
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 int opt[501][501],f[501][501]; 5 char str[501]; 6 void print(int left,int right) 7 { 8 if (left > right) return; 9 else 10 if (left == right) 11 { 12 if ((str[left] == ‘[‘) || (str[right] == ‘]‘)) printf("[]"); 13 else printf("()"); 14 } 15 else 16 if (f[left][right] == -1) 17 { 18 printf("%c",str[left]); 19 print(left + 1,right - 1); 20 printf("%c",str[right]); 21 } 22 else 23 { 24 print(left,f[left][right]); 25 print(f[left][right] + 1,right); 26 } 27 } 28 int main() 29 { 30 int t,len,i,j,k,l,Case; 31 char s[101],ch; 32 scanf("%d",&t); 33 scanf("%c",&ch); 34 for (Case = 1;Case <= t;Case++) 35 { 36 scanf("%c",&ch); 37 gets(str); 38 len = strlen(str); 39 if (len == 0) 40 { 41 printf("\n"); 42 if (Case != t) printf("\n"); 43 continue; 44 } 45 memset(opt,0,sizeof(opt)); 46 memset(f,0,sizeof(f)); 47 for (i = 0;i < len;i++) opt[i][i] = 1; 48 for (l = 1;l < len;l++) 49 { 50 for (i = 0;i < len - l;i++) 51 { 52 j = i + l; 53 opt[i][j] = 999999999; 54 if (((str[i] == ‘(‘) && (str[j] == ‘)‘)) || ((str[i] == ‘[‘) && (str[j] == ‘]‘))) 55 { 56 opt[i][j] = opt[i + 1][j - 1]; 57 f[i][j] = -1; 58 } 59 for (k = i;k < j;k++) 60 { 61 if (opt[i][j] > opt[i][k] + opt[k + 1][j]) 62 { 63 opt[i][j] = opt[i][k] + opt[k + 1][j]; 64 f[i][j] = k; 65 } 66 } 67 } 68 } 69 print(0,len - 1); 70 printf("\n"); 71 if (Case != t) printf("\n"); 72 } 73 }
[DP] UVA-1626 Brackets sequence