Brackets Sequence poj1141
题意:给一个括号串,要求输出增加最少的括号,使得整个括号串匹配后的括号序列。
思路:区间dp。记录路径的时候使用pos[i][j]数组,记录i到j中间的分割点,如果不用分割,那么记录为-1,否则是分割点的位置.
输出使用递归即可。
TIP:不要用scanf,会wa掉。用gets来读入。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<map>
#include<set>
#include<algorithm>
#include<sstream>
#include<string>
using namespace std;
const int N=107;
char a[107];
int dp[107][107];
int pos[107][107];
bool is(char a,char b)
{
if(a=='('&&b==')')
return 1;
if(a=='['&&b==']')
return 1;
return 0;
}
void show(int le,int ri)
{
// printf("le:%d ri:%d\n",le,ri);
if(le>ri)
return ;
if(le==ri)
{
if(a[le]=='('||a[le]==')')
{
printf("()");
}
else if(a[le]=='['||a[le]==']')
printf("[]");
return ;
}
if(pos[le][ri]==-1)
{
printf("%c",a[le]);
show(le+1,ri-1);
printf("%c",a[ri]);
return ;
}
show(le,pos[le][ri]);
show(pos[le][ri]+1,ri);
}
int main()
{
int T;
while(gets(a))
{
memset(pos,-1,sizeof pos);
memset(dp,0,sizeof dp);
int len=strlen(a);
for(int i=0;i<len;i++)
{
if(i+1<len)
{
if(is(a[i],a[i+1]))
dp[i][i+1]=2;
else
{
dp[i][i+1]=0;
}
}
dp[i][i]=0;
}
int n=len;
for(int i=1;i<n;i++)
{
for(int j=0;j+i<n;j++)
{
if(is(a[j],a[j+i]))
{
dp[j][j+i]=dp[j+1][j+i-1]+2;
pos[j][j+i]=-1;
}
for(int k=j;k+1<=j+i;k++)
{
if(dp[j][k]+dp[k+1][i+j]>=dp[j][j+i])
{
dp[j][j+i]=dp[j][k]+dp[k+1][i+j];
pos[j][j+i]=k;
}
}
}
}
// printf("pos[%d][%d]=%d\n",0,0,pos[0][0]);
show(0,n-1);
puts("");
}
return 0;
}