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

poj 1141Brackets Sequence[区间dp]

2013-08-04 11:10 211 查看
原题链接poj 1141 Brackets Sequence

由于对括号匹配的时候不只有一种方案,而本题要求要找最少的那种匹配方案,故可以用区间dp;

dp[i][j]表示从i到j之间为了匹配所需要的最少添加数。

状态转移方程 dp[i][j]=dp[i+1][j-1] (s[i]==s[j]);dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j])(i<=k<j);

又因为本题要输出匹配后的串,故需要把转移的路径记录下来,用pos[i][j]记录使dp[i][j]取最小值时的分开地方,

即上次动态转移方程中的最优的k值。然后递归输出。。。

参考代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 105
#define inf 0x7f7f7f7f
using namespace std;
char s
;
int dp

;
int pos

;
char match(int c)
{
if(c=='(')return ')';
else if(c=='[')return ']';
else return 'x';
}
void print(int l,int r)
{
if(dp[l][r]==0)
{
for(int i=l; i<=r; i++)
printf("%c",s[i]);
return;
}
if(l==r)
{
if(s[l]=='('||s[l]==')')printf("()");
else if(s[l]=='['||s[l]==']')printf("[]");
return ;
}
if(pos[l][r]==-1)
{
printf("%c",s[l]);
print(l+1,r-1);
printf("%c",s[r]);
return ;
}
else
{
print(l,pos[l][r]);
print(pos[l][r]+1,r);
}
return ;
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%s",s);
memset(dp,0,sizeof(dp));
memset(pos,0,sizeof(pos));
int n=strlen(s);
for(int i=0; i<n; i++)
{
dp[i][i]=1;
}
for(int l=1; l<n; l++)
for(int i=0; i+l<n; i++)
{
int j=i+l;
dp[i][j]=inf;
if(match(s[i])==s[j])
{
dp[i][j]=dp[i+1][j-1];
pos[i][j]=-1;
}
for(int k=i; k<j; k++)
if(dp[i][j]>dp[i][k]+dp[k+1][j])
{
dp[i][j]=dp[i][k]+dp[k+1][j];
pos[i][j]=k;
}
}
print(0,n-1);
printf("\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: