链接:点击打开链接
题意:给出一个括号序列向其中添加括号使得括号满足条件并且添加后长度最短,不允许出现(,[,),)(,([)],([(]这种类型的子序列
代码:
#include <vector>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
char s[205];
int dp[205][205];
vector<int> tmp,path[205][205];
int main(){ //dp[i][j]表示区间[i,j]中最少的匹配数
int i,j,l,k,len;
gets(s+1);
len=strlen(s+1);
memset(dp,0,sizeof(dp));
for(i=1;i<=len;i++)
for(j=1;j<=len;j++)
path[i][j].clear();
for(i=1;i<=len;i++){
dp[i][i]=1;
path[i][i].push_back(i);
}
for(l=2;l<=len;l++){ //用二维vector记录路径
for(i=1;i<=len-l+1;i++){
j=i+l-1;
if((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']')){
dp[i][j]=dp[i+1][j-1];
path[i][j]=path[i+1][j-1];
} //相当于预处理
else
dp[i][j]=INF;
for(k=i;k<=j;k++){
if(dp[i][j]>dp[i][k]+dp[k+1][j]){ //区间dp
dp[i][j]=dp[i][k]+dp[k+1][j];
tmp.assign(path[i][k].begin(),path[i][k].end());
tmp.insert(tmp.end(),path[k+1][j].begin(),path[k+1][j].end());
path[i][j]=tmp;
tmp.clear();
}
}
}
}
sort(path[1][len].begin(),path[1][len].end(),greater<int>());
for(i=1;i<=len;i++){
for(j=0;j<path[1][len].size();j++){ //遇到需要添加的直接输出
if(i==path[1][len][j]){
if(s[i]=='('||s[i]==')')
printf("()");
else if(s[i]=='['||s[i]==']')
printf("[]");
path[1][len].pop_back();
goto next;
}
}
printf("%c",s[i]);
next:;
}
printf("\n");
return 0;
}