1. 程式人生 > >[DP] UVA-1626 Brackets sequence

[DP] UVA-1626 Brackets sequence

str pan %d ini follow con fine file single

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 b1b2 . . . bm, if there exist such indices 1 ≤ i1 < i2 < . . . < in ≤ m, that aj = bij for all 1 ≤ j ≤ n.

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