Brackets Sequence
Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 26254 | Accepted: 7394 | 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.
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
题意:给一个只包含括号的串,问最少添加多少个串让该括号串合法,输出合法的括号串。
题解:我们考虑让括号串的第一括号匹配,那么,这个括号要么与已有的括号匹配,要么在某个位置添加一个与它匹配的括号。
我们可以用dp[l][r]表示让区间[l,r] 的括号串合法最少要添加多少个括号,转移就是:
1,如果第一个括号为')' 或 ']' ,显然只能在前面添加一个’(‘ 或']' 。
dp[l][r]=dp[l+1][r]+1;
2,如果第一个括号与第i个括号匹配,那么区间[l+1,i-1]和区间[i+1,r]的括号没有相互影响
dp[l][r]=min(dp[l+1][i-1]+dp[i+1][r])
3,如果在位置i和i+1之间添加一个括号与第一个括号匹配,那么区间[l+1,i]和区间[i+1,r] 之间没有影响
dp[l][r]=min(dp[l+1][i]+dp[i+1][r]+1)
在dp转移的过程中记录路径,最后输出方案即可。
代码如下:(注意由于空字符串也为合法串,所以输入的字符串有可能为空)
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<string>
#include<math.h>
#define nn 110
#define inff 0x7fffffff
#define eps 1e-8
typedef long long LL;
const LL inf64=LL(inff)*inff;
using namespace std;
int n;
char s[nn];
int dp[nn][nn];
int lj[nn][nn];
int dfs(int l,int r)
{
if(dp[l][r]!=-1)
return dp[l][r];
if(l>r)
return 0;
dp[l][r]=inff;
if(s[l]==')')
{
dp[l][r]=dfs(l+1,r)+1;
lj[l][r]=0;
return dp[l][r];
}
else if(s[l]==']')
{
dp[l][r]=dfs(l+1,r)+1;
lj[l][r]=0;
return dp[l][r];
}
int i;
for(i=2*l+2;i<=2*r+2;i++)
{
if(i%2)
{
if((s[l]=='('&&s[i/2]==')')||(s[l]=='['&&s[i/2]==']'))
{
if(dfs(l+1,i/2-1)+dfs(i/2+1,r)<dp[l][r])
{
dp[l][r]=dfs(l+1,i/2-1)+dfs(i/2+1,r);
lj[l][r]=i;
}
}
}
else
{
if((dfs(l+1,i/2-1)+dfs(i/2,r)+1)<dp[l][r])
{
dp[l][r]=dfs(l+1,i/2-1)+dfs(i/2,r)+1;
lj[l][r]=i;
}
}
}
return dp[l][r];
}
void go(int l,int r)
{
string re="";
if(l>r)
return ;
if(lj[l][r]==0)
{
if(s[l]==')')
printf("()");
else
printf("[]");
go(l+1,r);
return ;
}
if(lj[l][r]%2)
{
if(s[l]=='(')
{
printf("(");
go(l+1,lj[l][r]/2-1);
printf(")");
go(lj[l][r]/2+1,r);
}
else
{
putchar('[');
go(l+1,lj[l][r]/2-1);
putchar(']');
go(lj[l][r]/2+1,r);
}
}
else
{
if(s[l]=='(')
{
putchar('(');
go(l+1,lj[l][r]/2-1);
putchar(')');
go(lj[l][r]/2,r);
}
else
{
putchar('[');
go(l+1,lj[l][r]/2-1);
putchar(']');
go(lj[l][r]/2,r);
}
}
}
int main()
{
int i;
while(gets(s))
{
int len=strlen(s);
memset(dp,-1,sizeof(dp));
dfs(0,len-1);
//cout<<dfs(0,len-1)<<endl;
go(0,len-1);
puts("");
}
return 0;
}