题意:求增加括号数最小的序列
思路:见代码注释
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<stack>
#include<algorithm>
#include<vector>
#define y1 y12345
#define mx 110
#define inf 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
#define mod 1000000007
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int dp[mx][mx]; //dp[i][j]表示s[i]到s[j]所需要添加的最小括号数
int pre[mx][mx]; //记录路径
char s[mx];
//输出路径
void output(int b,int e){
if(b>e)return;
else if(b==e){
if(s[b]=='['||s[b]==']')
printf("[]");
else printf("()");
}
else if(pre[b][e]==-1){
printf("%c",s[b]);
output(b+1,e-1);
printf("%c",s[e]);
}
else{
output(b,pre[b][e]);
output(pre[b][e]+1,e);
}
return;
}
int main(){
memset(s,0,sizeof(s));
cin>>s+1;
int n=strlen(s+1);
memset(dp,0,sizeof(dp));
memset(pre,0,sizeof(pre));
for(int i=1;i<=n;i++)dp[i][i]=1; //初始化
for(int l=2;l<=n;l++){ //枚举j-i的长度
for(int i=1;i<=n-l+1;i++){
int j=i+l-1;
if(s[i]=='('&&s[j]==')'||s[i]=='['&&s[j]==']'){
dp[i][j]=dp[i+1][j-1]; //若s[i]与s[j]能配对,dp[i][j]初始化为dp[i+1][j-1]
pre[i][j]=-1;
}
else dp[i][j]=inf; //若不能,dp[i][j]初始化为最大值
for(int k=i;k<=j-1;k++){ //dp[i][j]=min(dp[i][k]+dp[k+1][j])
if(dp[i][j]>dp[i][k]+dp[k+1][j]){
dp[i][j]=dp[i][k]+dp[k+1][j];
pre[i][j]=k;
}
}
}
}
output(1,n);
printf("\n");
return 0;
}