您的位置:首页 > 产品设计 > UI/UE

POJ 1141 Brackets Sequence(动态规划)

2013-05-07 23:49 323 查看

题目大意

给你一个括号串(包括'(',')','[',']'),长度不超过 100,问你怎么添加最少的括号,使得这个括号串是合法的,输出添加括号后的合法括号串

做法分析

以长度划分阶段,定义状态:f[i][j] 表示,s(i)~s(j) 这一个字串需要添加多少括号使得其变为合法字串,状态转移:

f[i][j]=min{ f[i][k]+f[k+1][j] }

有一个特殊的地方就是:s(i) 和 s(j) 是两个匹配的括号,即:s(i)=='(' && s(j)==')' || s(i)=='[' && s[j]==']',那么 f[i][j] 还要和 f[i+1][j-1] 相比取最小者

最后输出的时候,递归的输出就行

这是今天无意间翻到的,不知道是什么时候看见了没有想法的一道题,没想到今天瞬间就把思路给秒了...这么水的DP,当时怎么会没想法呢?

参考代码

POJ 1141

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int N=106;

char buff
;
int f

, pre

;

void Print(int L, int R)
{
if(L>R) return;
if(L==R)
{
if(buff[L]=='[' || buff[L]==']') printf("[]");
else printf("()");
}
else if(pre[L][R]==-1)
{
printf("%c", buff[L]);
Print(L+1, R-1);
printf("%c", buff[R]);
}
else Print(L, pre[L][R]), Print(pre[L][R]+1, R);
}

int main()
{
while(gets(buff))
{
int n=(int)strlen(buff);
memset(f, 0, sizeof f);
for(int i=0; i<n; i++) f[i][i]=1, pre[i][i]=0;
for(int len=2; len<=n; len++)
{
for(int i=0; i+len-1<n; i++)
{
int j=i+len-1;
f[i][j]=0x3ffffff;
if(buff[i]=='[' && buff[j]==']' || buff[i]=='(' && buff[j]==')')
f[i][j]=f[i+1][j-1], pre[i][j]=-1;
for(int k=i; k<j; k++)
if(f[i][j]>f[i][k]+f[k+1][j])
f[i][j]=f[i][k]+f[k+1][j], pre[i][j]=k;
}
}
Print(0, n-1), printf("\n");
}
return 0;
}


题目链接 & AC通道

POJ 1141 Brackets Sequence
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: