Brackets Sequence
Time limit:1000 ms |
|
Memory limit:65536 K |
Total submissions:25087 |
|
Accepted:7069 |
|
Special Judge |
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
()[()]
Source
Northeastern Europe 2001.
Solution:
DP [I] [J] indicates adding at least a few parentheses from position I to position J to make matching. Pos [I] [J] =-1, STR [I] STR [J] is a pair of matching parentheses. Otherwise, the position where the STR [I] is recorded. STR [J] is divided into two parts. The output answer is recursive.
Code:
# Include <iostream> # include <stdio. h> # include <string. h> using namespace STD; const int maxn = 220; const int INF = 0x7fffffff; int POS [maxn] [maxn]; // Where do I and j separate int DP [maxn] [maxn]; // Add at least several characters from I to J char STR [maxn]; int Len; void print (int I, Int J) {if (I> J) return; // recursive exit if (I = J) {If (STR [I] = '(' | STR [I] = ') cout <"()"; else cout <"[]";} else if (Pos [I] [J] =-1) // The two sides are symmetric {cout <STR [I]; print (I + 1, J-1); cout <STR [J];} Else // It can be divided into {print (I, POS [I] [J]); print (Pos [I] [J] + 1, J );}} int main () {CIN> STR; Len = strlen (STR); memset (DP, 0, sizeof (DP); For (INT I = 0; I <Len; I ++) DP [I] [I] = 1; for (int K = 1; k <Len; k ++) // length for (INT I = 0; I + k <Len; I ++) // start point {Int J = I + k; DP [I] [J] = inf; if (STR [I] = '(' & STR [J] = ')') | (STR [I] = '[' & STR [J] = ']') {DP [I] [J] = DP [I + 1] [J-1]; POS [I] [J] =-1; // temporarily make it equal to-1} For (INT mid = I; Mid <j; Mid ++) // This must be executed. {If (DP [I] [J]> (DP [I] [Mid] + dp [Mid + 1] [J]) {DP [I] [J] = DP [I] [Mid] + dp [Mid + 1] [J]; POS [I] [J] = mid ;}}} print (0, len-1); cout <Endl; return 0 ;}