UVA-1626 Brackets sequence (简单区间DP)

题目大意:给一个有小括号和中括号组成的序列,满足题中的三个条件时,是合法的。不满足时是不合法的,问将一个不合法的序列最少添加几个括号可以使之变成合法的。输出最短合法序列。

题目分析:这是《入门经典》上的一道例题。如果仅让求最短序列是极简单的,定义dp(i,j)表示将区间 i~j 变为合法添加的最小字符数.

      则 dp(i,j)=dp(i+1,j-1)   (i与j能匹配时),    dp(i,j)=min(dp(i,k)+dp(k+1,j))。

但是,输出的时候就比较慢了。从左往右通过比较选择最优方案递归输出(看的书上代码)。

 

代码如下:

# include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>
using namespace std;
char p[105];
int dp[105][105];
const int INF=100000;
bool match(int x,int y)
{
    if(p[x]=='('&&p[y]==')')
        return true;
    if(p[x]=='['&&p[y]==']')
        return true;
    return false;
}
void DP()
{
    int len=strlen(p);
    for(int l=1;l<=len;++l){
        for(int i=0;i+l-1<len;++i){
            int r=i+l-1;
            if(l==1){
                dp[i][r]=1;
                continue;
            }
            if(l==2){
                if(match(i,r))
                    dp[i][r]=0;
                else
                    dp[i][r]=2;
                continue;
            }
            dp[i][r]=INF;
            if(match(i,r))
                dp[i][r]=dp[i+1][r-1];
            for(int k=i;k<r;++k){
                dp[i][r]=min(dp[i][r],dp[i][k]+dp[k+1][r]);
            }
        }
    }
}
void print(int i,int j)
{
    if(i>j)
        return ;
    if(i==j){
        if(p[i]=='('||p[i]==')')
            printf("()");
        else
            printf("[]");
        return ;
    }
    int ans=dp[i][j];
    if(match(i,j)&&ans==dp[i+1][j-1]){
        printf("%c",p[i]);
        print(i+1,j-1);
        printf("%c",p[j]);
        return ;
    }
    for(int k=i;k<j;++k){
        if(ans==dp[i][k]+dp[k+1][j]){
            print(i,k);
            print(k+1,j);
            return ;
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    getchar();
    while(T--)
    {
        getchar();
        gets(p);
        int len=strlen(p);
        if(len>0){
            DP();
            print(0,len-1);
        }
        printf("\n");
        if(T)
            printf("\n");
    }
    return 0;
}

  

posted @ 2015-09-08 11:37  20143605  阅读(195)  评论(0编辑  收藏  举报