状态转移方程: dp[i][j] = min( dp[i][j], dp[i+1][j-1] ); //( str[i] == '(' && str[j] == ')' ) || ( str[i] == '[' && str[j] == ']' )
dp[i][j] = min( dp[i][j], dp[i+k][k] + dp[k+1][j] ); //已点k把区间[i,j]分为两个子区间 取最小值。
区间路径表示 path[i][j] = k;表示区间[i,]由k点将区间分成2个子区间。
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<math.h>
#include<functional>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 105;
const int inf = 1<<30;
int len;
int dp[maxn][maxn];
char str[maxn],path[maxn][maxn];
void GetDp()
{
memset(dp,0,sizeof(dp));
for( int i = 0; i < len; i ++ )
dp[i][i] = 1;
for( int r = 1; r < len; r ++ ){
for( int i = 0; i+r < len; i ++ ){
int j = i+r;
dp[i][j] = inf;
if( ( str[i] == '(' && str[j] == ')' ) || ( str[i] == '[' && str[j] == ']' ) ){
if( dp[i][j] > dp[i+1][j-1] ){
dp[i][j] = dp[i+1][j-1];
path[i][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];
path[i][j] = k;
}
}
}
}
}
void OutPut( int ld,int rd )
{
if( ld == rd ){
if( str[ld] == '(' || str[ld] == ')' ) printf("()");
else printf("[]");
}
else if( ld < rd )
{
if( path[ld][rd] == -1 ){
printf("%c",str[ld]);
OutPut( ld+1,rd-1 );
printf("%c",str[rd]);
}
else{
OutPut( ld,path[ld][rd] );
OutPut( path[ld][rd]+1,rd );
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.txt","r",stdin);
#endif
scanf("%s",str);
len = strlen(str);
if( len != 0 ){
GetDp();
OutPut(0,len-1);
puts("");
}
puts("");
return 0;
}