Description
![sequence](http://www.cfanz.cn/uploads/png/2014/03/26/10/716b4106E9.png)
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
()[()]
题意:定义满足
1.空序列
2.()(X)及括号和其括起来的合法序列
3.【】要求和()相同
都是合法的串。
1.如果s[i]和s[j]配对,那么d(i,j)=d(i+1,j-1);
2.如果字符串有2个及以上的字符,可以将原本的字符串分为两个,转移为d(i,j)=d(i,k)+d(k+1,j);(配对的情况下也要考虑这种情况,因为1的转移未必是最优解,比如[][],如果只用1转移,就是][,要添2个括号,所以要进行2的转移)。
这题最坑爹的莫过于输入输出,第一个数下面要一个空行,每个input之间要一个空行,每个output之间要一个空行。
输出换行真是坑死我。。。具体讲解在紫书上(真佩服刘大爷的智商)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
char s[105];
int dp[105][105];
bool match(int a,int b){
if(s[a]=='('&&s[b]==')')
return true;
else if(s[a]=='['&&s[b]==']')
return true;
else
return false;
}
void print(int i,int j){
if(i>j)
return;
if(i==j){
if(s[i]==')'||s[i]=='(')
printf("()");
else
printf("[]");
return;
}
int ans=dp[i][j];
int k;
if(match(i,j)&&ans==dp[i+1][j-1]){
printf("%c",s[i]);
print(i+1,j-1);
printf("%c",s[j]);
return;
}
for(k=i;k<j;k++){
if(ans==dp[i][k]+dp[k+1][j]){
print(i,k);
print(k+1,j);
return;
}
}
}
int main(){
int i,j,k;
int kase;
scanf("%d",&kase);
int len;
int flag=0;
getchar();
while(kase--){
gets(s);
gets(s);
len=strlen(s);
if(!len){
if(flag++)
printf("\n");
printf("\n");
continue;
}
for(i=0;i<len;i++){
dp[i][i]=1;
dp[i+1][i]=0;
}
for(i=len-2;i>=0;i--){//dp
for(j=i+1;j<len;j++){
dp[i][j]=len;
if(match(i,j))
dp[i][j]=min(dp[i][j],dp[i+1][j-1]);
for(k=i;k<j;k++){
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
}
}
}
if(flag++)
printf("\n");
print(0,len-1);
printf("\n");
//memset(dp,0,sizeof(dp));
}
return 0;
}