http://www.cnblogs.com/20143605--pcx/p/4791122.html
Let us define a regular brackets sequence in the following way:
(), [], (()), ([]), ()[], ()[()]
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.
The input file contains at most 100 brackets (characters '(', ')', '[' and ']') that are situated on a single line without any other characters among them.
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.
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.
(), [], (()), ([]), ()[], ()[()]
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 变为合法添加的最小字符数.
则 dp(i,j)=dp(i+1,j-1) (i与j能匹配时), dp(i,j)=min(dp(i,k)+dp(k+1,j))。
但是,输出的时候就比较慢了。从左往右通过比较选择最优方案递归输出(看的书上代码)。
char
p[105];
int
dp[105][105];
const
int
INF=100000;
bool
match(
int
x,
int
y)
{
if
(p[x]==
'('
&&p[y]==
')'
)
return
true
;
if
(p[x]==
'['
&&p[y]==
']'
)
return
true
;
return
false
;
}
void
DP()
{
int
len=
strlen
(p);
for
(
int
l=1;l<=len;++l){
for
(
int
i=0;i+l-1<len;++i){
int
r=i+l-1;
if
(l==1){
dp[i][r]=1;
continue
;
}
if
(l==2){
if
(match(i,r))
dp[i][r]=0;
else
dp[i][r]=2;
continue
;
}
dp[i][r]=INF;
if
(match(i,r))
dp[i][r]=dp[i+1][r-1];
for
(
int
k=i;k<r;++k){
dp[i][r]=min(dp[i][r],dp[i][k]+dp[k+1][r]);
}
}
}
}
void
print(
int
i,
int
j)
{
if
(i>j)
return
;
if
(i==j){
if
(p[i]==
'('
||p[i]==
')'
)
printf
(
"()"
);
else
printf
(
"[]"
);
return
;
}
int
ans=dp[i][j];
if
(match(i,j)&&ans==dp[i+1][j-1]){
printf
(
"%c"
,p[i]);
print(i+1,j-1);
printf
(
"%c"
,p[j]);
return
;
}
for
(
int
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
T;
scanf
(
"%d"
,&T);
getchar
();
while
(T--)
{
getchar
();
gets
(p);
int
len=
strlen
(p);
if
(len>0){
DP();
print(0,len-1);
}
printf
(
"\n"
);
if
(T)
printf
(
"\n"
);
}
return
0;
}