定义下列为正规括号序列
1:空的是正规括号序列
2:如果s是正规括号序列 那么[s]和(s)也是正规括号序列
3:如果A和B都是正规括号序列,那么AB也是正规括号序列
下面的都是正规括号序列 () [()] [] ()[]
下面的都不是正规括号序列 ( [ ] )(
输入员工由( ) [ ]构成的序列添加尽量少的括号 得到正规括号序列 并输出
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define eps 1e-10
#define maxl 1005
#define mem(i,j) memset(i,j,sizeof(i))
int n;
string s;
int d[maxl][maxl];//d[i][j]表示i~j之间的区间至少需要添加几个括号 所以答案为d[0][n-1]
bool match(char a,char b){
if(a=='('&&b==')') return true;
if(a=='['&&b==']') return true;
return false;
}
void dp(){
memset(d,0,sizeof(d));
for(int i=0;i<n;i++){//初始化
d[i][i]=1;//这种情况只有一个 所以只需要添加一个凑成一对就ok 为1
}
for(int i=n-2;i>=0;i--){//最后就是0 n-1
for(int j=i+1;j<n;j++){
d[i][j]=n;//最多需要匹配多少
if(match(s[i],s[j])) d[i][j]=min(d[i][j],d[i+1][j-1]);//如果i j匹配的话
for(int k=i;k<j;k++)
d[i][j]=min(d[i][j],d[i][k]+d[k+1][j]);
}
}
}
void print(int i,int j){
if(i>j) return ;
if(i==j){//直接输出就好了
if(s[i]=='('||s[i]==')') printf("()");
else printf("[]");
return ;
}
int ans=d[i][j];
if(match(s[i],s[j])&&ans==d[i+1][j-1]){
printf("%c",s[i]);print(i+1,j-1);printf("%c",s[j]);//按顺序输出就好
return ;
}
for(int k=i;k<j;k++)
if(ans==d[i][k]+d[k+1][j]){
print(i,k);print(k+1,j);
return ;
}
}
int main()
{
freopen("in.txt", "r", stdin);
int t;
cin>>t;
getchar();
while(t--){
getchar();
getline(cin,s);
n=s.length();
dp();
print(0,n-1);
if(t!=0) cout<<endl;
cout<<endl;
}
}