Brackets Sequence
题意:
输入
输入包含在一行中给出的至多100个括号(字符’(’,’)’,’[‘和’]’),其中没有其他的字符。
输出
输出一行,给出包含了给出序列作为子序列的具有最小可能长度的合法括号序列。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
#define ll long long
const int inf=0x3f3f3f3f;
const int maxn=200;
char s[maxn];
//位置信息,括号成功匹配时为 -1
int v[maxn][maxn];
//区间i、j匹配添加括号后的区间长度
int dp[maxn][maxn];
void print(int l,int r)
{
if(r<l) return;
if(l==r)
{
if(s[l]=='(' || s[l]==')') printf("()");
else printf("[]");
return;
}
if(v[l][r]==-1)
{
if(s[l]=='(')
{
printf("(");
print(l+1,r-1);
printf(")");
} else{
printf("[");
print(l+1,r-1);
printf("]");
}
}else{
print(l,v[l][r]);
print(v[l][r]+1,r);
}
}
int main()
{
scanf("%s",s);
int len=strlen(s);
memset(dp,0,sizeof(dp));
for(int i=0;i<len;i++) dp[i][i]=2;
for(int j=1;j<len;j++)
for(int i=0;i+j<len;i++)
{
dp[i][i+j]=inf;
for(int k=i;k<i+j;k++)
{
if(dp[i][i+j]>dp[i][k]+dp[k+1][i+j])
{
dp[i][i+j]=dp[i][k]+dp[k+1][i+j];
v[i][i+j]=k;
}
}
if(s[i]=='('&&s[i+j]==')'||s[i]=='['&&s[i+j]==']')
if(dp[i][i+j]>dp[i+1][i+j-1]+2)
{
dp[i][i+j]=dp[i+1][i+j-1]+2;
v[i][i+j]=-1;
}
}
print(0,len-1);
printf("\n");
return 0;
}