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

poj 1141 Brackets Sequence(区间DP记录路径)

2015-10-23 20:39 369 查看
题目链接:

http://poj.org/problem?id=1141

题目大意:

给一个不完全匹配的括号序列,问最少需要增加多少个括号能够使括号序列完全匹配,输出完全匹配以后的序列。

思路:

区间DP。我们设dp[i][j]代表i~j区间里面使得括号完全匹配最少需要增加的括号数。

那么如果s[i]和s[j]是匹配的,就有dp[i][j]=dp[i+1][j-1]。

然后就在i~j之间枚举k,同时更新dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j])。

这样我们就能够知道最少需要增加的括号数了。接下来我们就要考虑记录路径的问题了。

我们可以设一个p[i][j],初始化为-1。如果p[i][j]=k,就表示在区间i~j里面,在k这个位置有切入点需要添加新的括号。

所以我们可以采用递归的方式,来打印出路径。

代码:

#include<stdio.h>
#include<string.h>
char s[105],c[105];
int p[105][105];
void print(int i,int j)
{
if(i>j)return;
if(i==j){
if(s[i]=='('||s[i]==')')printf("()");
else printf("[]");
return;
}
if(i<j)
{
if(p[i][j]==-1){

if(s[i]=='(')
{
printf("(");
print(i+1,j-1);
printf(")");
}
else if(s[i]=='['){
printf("[");
print(i+1,j-1);
printf("]");
}
}
else
{
print(i,p[i][j]);
print(p[i][j]+1,j);
}
}
}
int main()
{

int  dp[105][105],i,j,k,l;
while(gets(c))
{
l=strlen(c);
for(i=0;i<l;i++)
s[i+1]=c[i];
memset(dp,0,sizeof(dp));
memset(p,-1,sizeof(p));
for(i=1;i<=l;i++)
dp[i][i]=1;
for(k=2;k<=l;k++)
{
for(i=1;i<=l-k+1;i++)
{
int zhong=i+k-1;
if(s[i]=='('&&s[zhong]==')'||s[i]=='['&&s[zhong]==']')
{dp[i][zhong]=dp[i+1][zhong-1];
p[i][zhong]=-1;}
else dp[i][zhong]=99999999;
for(j=i;j<zhong;j++)
{
if(dp[i][zhong]>dp[i][j]+dp[j+1][zhong])
{
dp[i][zhong]=dp[i][j]+dp[j+1][zhong];
p[i][zhong]=j;
}
}

}
}
// printf("%d\n",l);
print(1,l);
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: