题目链接:http://poj.org/problem?id=1141
//poj1141
//题目意思,给出不一定规则的括号组合要把它们规则化
//这题用动态规划解决:定义两个二维数组num[i][j],pos[i][j],
//分别表示i到j所要添加的括号数和i至j要分开的位置,
//其中num[][]是为pos[][]服务的
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
int len;
char str[102];
int num[102][102];//i到j所要添加的括号数
int pos[102][102];//i至j要分开的位置
void dpSet()
{
int i,j,k;
memset(num,0,sizeof(num));
for(i=0;i<len;i++)
num[i][i]=1;//若只有一边的括号当然要添加一个
for(j=1;j<len;j++)//j表示两端的下标间距
for(i=0;i<len-j;i++)//左端下标
{
int right=i+j;//右端的下标
num[i][right]=100000;
if(str[i]=='('&&str[right]==')'||(str[i]=='['&&str[right]==']'))
{
pos[i][right]=-1;//表示符合
num[i][right]=num[i+1][right-1];//两端符合后添加数与内部相同
}
for(k=i;k<right;k++)
if(num[i][right]>num[i][k]+num[k+1][right])
{
num[i][right]=num[i][k]+num[k+1][right];
pos[i][right]=k;
}
}
}
void dpFind(int x,int y)//x,y表示分别表示左右两端下标
{
if(x>y)return;
else if(x==y)
{
if(str[x]=='('||str[x]==')')
printf("()");
else printf("[]");
}
else
{
if(pos[x][y]==-1)
{
printf("%c",str[x]);
dpFind(x+1,y-1);
printf("%c",str[y]);
}
else
{
dpFind(x,pos[x][y]);
dpFind(pos[x][y]+1,y);
}
}
}
int main()
{
while(gets(str))
{
len=strlen(str);
dpSet();
dpFind(0,len-1);
printf("\n");
}
return 0;
}