1141 DP 括号序列
自底向上递推,打表,分析补全括号的各种最优情况。
#include <iostream> #include <string> #include <iomanip> using namespace std; #define max 110 #define INF 10000000; int d[max][max]; string ans[max][max]; char s[110]; int n; char rev(char a) { if(a=='(') return ')'; else if(a==')') return '('; else if(a=='[') return ']'; else if(a==']') return '['; } void dp() { for(int i=1;i<=n;i++){ d[i][i-1]=0; d[i][i]=1; if(s[i]==')'||s[i]=='(') ans[i][i]="()"; else ans[i][i]="[]"; } for(int p=1;p<=n-1;p++) { for(int i=1;i<=n-p;i++){ int j=i+p; d[i][j]=INF; if((s[i]=='('&&s[j]==')') || (s[i]=='['&&s[j]==']')) { if(d[i][j]>d[i+1][j-1]) { d[i][j]=d[i+1][j-1]; ans[i][j]=s[i]+ans[i+1][j-1]+s[j]; } } if(s[i]=='('||s[i]=='[') { if(d[i][j]>d[i+1][j]+1){ d[i][j]=d[i+1][j]+1; ans[i][j]=s[i]+ans[i+1][j]+rev(s[i]); } } if(s[j]==')'||s[j]==']'){ if(d[i][j]>d[i][j-1]+1){ d[i][j]=d[i][j-1]+1; ans[i][j]=rev(s[j])+ans[i][j-1]+s[j]; } } for(int k=i;k<=j-1;k++){ if(d[i][j]>d[i][k]+d[k+1][j]){ ans[i][j]=ans[i][k]+ans[k+1][j]; d[i][j]=d[i][k]+d[k+1][j]; } } } } } //void print() //{ // for(int i=1;i<=n;i++){ // for(int j=1;j<=n;j++) // cout<<setw(12)<<d[i][j]<<ans[i][j]; // cout<<endl; // } // cout<<endl; //} int main() { gets(s+1); n=strlen(s+1); dp(); cout<<ans[1][n]<<endl; return 0; }