UVA - 1626 Brackets sequence

题目链接

给你一个括号序列,输出一个前后括号都匹配的补全序列,且补的字符尽量少。

对一个串s来说,只会有两种情况:1、(t)或【t】转移到t 2、有两个字符,分段转移。为了保证是最小值,一定要考虑情况二。

实际处理时,dp要开成二维,一个表示开头一个表示结尾。

吐槽一下UVA的输入输出,太恶心了成心卡你。

AC代码:

(非常抱歉不会用刘汝佳的输入)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn=110;
char s[maxn];
int d[maxn][maxn];
int n;

int match(char a,char b)
{
    return (a=='('&&b==')')||(a=='['&&b==']');
}

void dp()
{
    for(int i=0;i<n;i++)
    {
        d[i][i]=1;
        d[i+1][i]=0;//ÒâÒåΪºÎ£¿
    }

    for(int i=n-2;i>=0;i--)
        for(int j=i+1;j<n;j++)
        {
            d[i][j]=n;
            if(match(s[i],s[j]))
                d[i][j]=min(d[i][j],d[i+1][j-1]);
            for(int k=i;k<j;k++)
                d[i][j]=min(d[i][j],d[i][k]+d[k+1][j]);
        }
}

void print(int i,int j)
{
    if(i>j) return;
    if(i==j)
    {
        if(s[i]=='('||s[i]==')')
            printf("()");
        else
            printf("[]");
        return;
    }

    int ans=d[i][j];
    if(match(s[i],s[j])&&ans==d[i+1][j-1])
    {
        printf("%c",s[i]);print(i+1,j-1);printf("%c",s[j]);
        return;
    }
    for(int k=i;k<j;k++)
        if(ans==d[i][k]+d[k+1][j])
        {
            print(i,k);print(k+1,j);
            return;
        }
}


int main()
{
    int t;
    cin>>t;
    getchar();
    while(t--)
    {
        gets(s);
        gets(s);
        n=strlen(s);
        memset(d,-1,sizeof(d));
        dp();
        print(0,n-1);
        cout<<endl;
        if(t) cout<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41333002/article/details/82260901