题意:给你一串只包含'(',')','['和']'的字符串
求所有()和【】都匹配的增加字符最少的字符串
假如有多个输出任意一个
思路:由于一个字符最后会完全匹配
两个已经相连的区间没有约束条件可以直接连接不需要任何代价
所以转移方程为DP [i] [j] = DP [I] [K] + DP [K + 1] [j]的;
最后需要打印路径
打印分两种打印
1两个匹配字符都是旧字符
2一个旧字符匹配一个新的字符
ACcode:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
using namespace std;
char s[200];
int dp[110][110];
int vis[110][110];
void print(int i,int j){
if( i > j) return ; // 注意过程中 i 可能会大于j 上一层 i==j i-1 ,j+1
if(i == j){ //找到新旧匹配
if(s[i] =='('|| s[i]==')')
printf("()");
else
printf("[]");
return ;
}
if(vis[i][j] == -1){ //旧字符匹配
putchar(s[i]);
print(i+1,j-1);
putchar(s[j]);
}else{
print(i,vis[i][j]);
print(vis[i][j]+1,j);
}
}
int main(){
scanf("%s",s+1);
int n = strlen(s+1);
for(int i=1;i<=n;i++) {
dp[i][i]=1;
vis[i][i]=-1;
}
for(int len=1;len<n;len++){
for(int i=1;i<=n-len;i++){
int j=i+len;
dp[i][j]= 0x7fffffff;
vis[i][j]=-1;
if((s[i]== '(' && s[j] == ')')||(s[i] == '[' && s[j] == ']')) {
dp[i][j]=dp[i+1][j-1];
}
for(int k=i;k<j;k++){
if(dp[i][j] >(dp[i][k]+dp[k+1][j])){
dp[i][j]=dp[i][k]+dp[k+1][j];
vis[i][j]=k; //新旧匹配的点
}
}
}
}
print(1,n);
printf("\n");
return 0;
}