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 a 1a 2...a n is called a subsequence of the string b 1b 2...b m, if there exist such indices 1 ≤ i 1 < i 2 < ... < i n ≤ m, that a j=b ij for all 1 ≤ j ≤ n.
Input
The input contains at most 100 brackets (characters '(', ')', '[' and ']') that are situated on a single line without any other characters among them.
Output
Write a single line that contains some regular brackets sequence that has the minimal possible length and contains the given sequence as a subsequence.
Example
input | output |
---|---|
|
|
思路:dp[i][j]为区间i,到j最少加多少个才能合法,先用区间dp模板把dp[1][n]求出来,但是在求的过程中记录dp[i][j]的决策点
k,dp[i][j]=min(dp[i][k],dp[k+1][j]) 在求的时候用一个pos数组记录决策点k,表示在k这个位置分开可以求出i,j区间括号匹配的最小值;当然在str[i]与str[j]匹配的时候 dp[i][j]=dp[i+1][j-1];
那么怎么打印呢,递归打印 print(1,n)
当 l>r 不合法,
l==r 如果str[l]为(,)直接输出()其他输出[],
如果 l<r
如果pos[l][r]==-1 表示没有找到中断点,那么str[l]是 和str[r]匹配的,
else 那就递归 print(l,pos[l][r]),print(pos[l][r]+1,r)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstdlib>
#include<deque>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<double,double>P;
const int len=1e2+5;
const double pi=acos(-1.0);
const ll mod=1e8+7;
int dp[len][len];
int pos[len][len];
int n;
char str[len];
void print(int l,int r)
{
if(l>r)return ;
if(l==r)
{
if(str[l]=='('||str[l]==')')printf("()");
else printf("[]");
}
else
{
if(pos[l][r]==-1)
{
putchar(str[l]);
print(l+1,r-1);
putchar(str[r]);
}
else
{
print(l,pos[l][r]);
print(pos[l][r]+1,r);
}
}
}
int main()
{
while(~scanf("%s",str+1))
{
n=strlen(str+1);
memset(dp,0x3f,sizeof(dp));
memset(pos,-1,sizeof(pos));
for(int i=1;i<=n;++i)dp[i][i]=1,dp[i][i-1]=0;
for(int le=2;le<=n;++le)
{
for(int i=1;i+le-1<=n;++i)
{
int j=i+le-1;
if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']')dp[i][j]=min(dp[i+1][j-1],dp[i][j]);
for(int k=i;k<j;++k)
{
if(dp[i][j]>dp[i][k]+dp[k+1][j])
{
pos[i][j]=k;
dp[i][j]=dp[i][k]+dp[k+1][j];
}
}
}
}
print(1,n);
puts("");
}
}