题意:给定字符串,问输出用插入最少的括号使之合法的字符串。
分析:dp[i][j] 表示i到j需要插入的括号数,v[i][j]表示需要插入的位置,v[i][j]=-1表示不需要插入,如果str[i]==str[j],dp[i][j]=dp[i+1][j-1],v[i][j]=-1; 否则dp[i][j]=min(dp[i][k],dp[k+1][j]),i <= k< j,v[i][j]=k,剩下的就是输出。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAX_N 105
#define inf 0x3f3f3f3f
using namespace std;
char str[MAX_N];
int dp[MAX_N][MAX_N];
int v[MAX_N][MAX_N];
void print(int i,int j)
{
if(i>j)
return ;
else if(i==j)
{
if(str[i]=='('||str[i]==')')
printf("()");
if(str[i]=='['||str[i]==']')
printf("[]");
}
else if(v[i][j]==-1)
{
printf("%c",str[i]);
print(i+1,j-1);
printf("%c",str[j]);
}
else
{
print(i,v[i][j]);
print(v[i][j]+1,j);
}
return ;
}
int main(void)
{
scanf("%[^\n]",str);
int len=strlen(str);
memset(v,-1,sizeof(v));
for(int i=0;i<len;i++)
dp[i][i]=1;
for(int l=1;l<len;l++)
{
for(int i=0;i<len-l;i++)
{
int j=i+l;
dp[i][j]=inf;
if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))
{
dp[i][j]=dp[i+1][j-1];
v[i][j]=-1;
// continue;
}
for(int k=i;k<j;k++)
{
if(dp[i][k]+dp[k+1][j]<dp[i][j])
{
dp[i][j]=dp[i][k]+dp[k+1][j];
v[i][j]=k;
}
}
}
}
print(0,len-1);
printf("\n");
return 0;
}