poj1141

题意:给一组小括号与中括号的序列,添加最少的字符,使该序列变为合法序列,输出该合法序列。

分析: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]是从哪得来的。

View Code
#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;
}

转载于:https://www.cnblogs.com/rainydays/archive/2011/07/04/2097550.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值