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

时间:2022-04-21 08:14:28

题目链接:

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;
}