Uva--1626(动规,路径)
2014-09-06 14:58:25
1626 - Brackets sequence
Let us define a regular brackets sequence in the following way:
- Empty sequence is a regular sequence.
- If S is a regular sequence, then (S) and [S] are both regular sequences.
- 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 a1a2...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
()[()]
思路:小白书例题,dp[i][j]表示匹配区间[i,j]内的字符的最优解。不多说了,注意一个trick:输入可能为空串,所以要用gets(or fgets)函数输入。
1 /************************************************************************* 2 > File Name: Uva1626.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Sat 06 Sep 2014 12:41:55 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 const int INF = 1 << 29; 16 17 int T,len; 18 int dp[105][105]; 19 char s[105]; 20 21 bool Match(char a,char b){ 22 if(a == '(' && b == ')') return true; 23 if(a == '[' && b == ']') return true; 24 return false; 25 } 26 27 void Print(int x,int y){ 28 if(x > y) return; 29 if(x == y){ 30 if(s[x] == '(' || s[x] == ')') printf("()"); 31 else printf("[]"); 32 return; 33 } 34 if(Match(s[x],s[y]) && dp[x][y] == dp[x + 1][y - 1]){ 35 printf("%c",s[x]); 36 Print(x + 1,y - 1); 37 printf("%c",s[y]); 38 } 39 else{ 40 int k; 41 for(k = x; k < y; ++k) 42 if(dp[x][y] == dp[x][k] + dp[k + 1][y]) break; 43 Print(x,k); 44 Print(k + 1,y); 45 } 46 } 47 48 int main(){ 49 scanf("%d%*c%*c",&T); 50 while(T--){ 51 gets(s + 1); 52 getchar(); 53 len = strlen(s + 1); 54 memset(dp,0,sizeof(dp)); 55 for(int i = 0; i < 105; ++i) dp[i][i] = 1; 56 for(int i = len - 1; i >= 1; --i){ 57 for(int j = i + 1; j <= len; ++j){ 58 dp[i][j] = INF; 59 if(Match(s[i],s[j])) 60 dp[i][j] = min(dp[i][j],dp[i + 1][j - 1]); 61 for(int k = i; k < j; ++k) 62 dp[i][j] = min(dp[i][j],dp[i][k] + dp[k + 1][j]); 63 } 64 } 65 Print(1,len); 66 printf("\n"); 67 if(T) printf("\n"); 68 } 69 return 0; 70 }