题意:给一组小括号与中括号的序列,添加最少的字符,使该序列变为合法序列,输出该合法序列。
分析:dp,f[i][j]表示从i位到j位的序列变为合法序列最少添加多少个字符。
如果匹配st[s]与st[e]匹配,那么f[s][e] = f[s + 1][e - 1];否则f[s][e] = f[s][k] + f[k + 1][e];
我们还要用v[][]记录每个f[s][e]是从哪得来的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
usingnamespace std;
#define maxn 300
char st[maxn];
int f[maxn][maxn], v[maxn][maxn];
bool match(char a, char b)
{
if (a =='('&& b ==')')
returntrue;
if (a =='['&& b ==']')
returntrue;
returnfalse;
}
char other(char a)
{
if (a =='(')
return')';
if (a =='[')
return']';
if (a ==')')
return'(';
return'[';
}
void output(int s, int e)
{
if (s > e)
return;
if (s == e)
{
if (st[s] =='('|| st[s] ==')')
printf("()");
else
printf("[]");
return;
}
if (v[s][e] ==-1)
{
putchar(st[s]);
output(s +1, e -1);
putchar(st[e]);
return;
}
output(s, v[s][e]);
output(v[s][e] +1, e);
}
int main()
{
//freopen("t.txt", "r", stdin);
if (gets(st) == NULL)
return0;
int len = strlen(st);
memset(f, -1, sizeof(f));
memset(v, -1, sizeof(v));
for (int i =0; i < len; i++)
{
f[i][i] =1;
f[i +1][i] =0;
}
for (int i =1; i < len; i++)
{
for (int j =0; j < len - i; j++)
{
int s = j, e = j + i;
if (match(st[s], st[e]))
f[s][e] = f[s +1][e -1];
for (int k = s; k < e; k++)
if (f[s][e] > f[s][k] + f[k +1][e] || f[s][e] ==-1)
{
f[s][e] = f[s][k] + f[k +1][e];
v[s][e] = k;
}
}
}
output(0, len -1);
putchar('\n');
return0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
usingnamespace std;
#define maxn 300
char st[maxn];
int f[maxn][maxn], v[maxn][maxn];
bool match(char a, char b)
{
if (a =='('&& b ==')')
returntrue;
if (a =='['&& b ==']')
returntrue;
returnfalse;
}
char other(char a)
{
if (a =='(')
return')';
if (a =='[')
return']';
if (a ==')')
return'(';
return'[';
}
void output(int s, int e)
{
if (s > e)
return;
if (s == e)
{
if (st[s] =='('|| st[s] ==')')
printf("()");
else
printf("[]");
return;
}
if (v[s][e] ==-1)
{
putchar(st[s]);
output(s +1, e -1);
putchar(st[e]);
return;
}
output(s, v[s][e]);
output(v[s][e] +1, e);
}
int main()
{
//freopen("t.txt", "r", stdin);
if (gets(st) == NULL)
return0;
int len = strlen(st);
memset(f, -1, sizeof(f));
memset(v, -1, sizeof(v));
for (int i =0; i < len; i++)
{
f[i][i] =1;
f[i +1][i] =0;
}
for (int i =1; i < len; i++)
{
for (int j =0; j < len - i; j++)
{
int s = j, e = j + i;
if (match(st[s], st[e]))
f[s][e] = f[s +1][e -1];
for (int k = s; k < e; k++)
if (f[s][e] > f[s][k] + f[k +1][e] || f[s][e] ==-1)
{
f[s][e] = f[s][k] + f[k +1][e];
v[s][e] = k;
}
}
}
output(0, len -1);
putchar('\n');
return0;
}