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

括号序列问题

有几个注意点:

(1)不能用scanf("%s", str), 而要用gets(str),因为输入可能含有空格(空序列'' "符合要求);

(2)‘ l ’表示所考虑对象的长度, 从0到n-1枚举(故单独处理dp[i][i]);

(3)dp[i][j]表示‘ i ’到 ‘ j ’的最小长度,也可以换种意义,表示‘ i ’到‘ j ’的最小添加长度,此时所有dp[i][j]要做适当调整。

具体代码:

View Code
#include<stdio.h>
#include<string.h>
char str[120];
int n, dp[120][120], mark[120][120];
void solve()
{
    int i, j, k, l;
    for(i=0;i<n;i++) dp[i][i]=1;
    for(l=1;l<n;l++)
        for(i=0;i<n-l;i++)
        {
            j=i+l;
            dp[i][j]=(1<<15);
            if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']')
            {
                dp[i][j]=dp[i+1][j-1];
                mark[i][j]=-1;
            }
            for(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];
                    mark[i][j]=k;
                }
        }
}
void out(int ps, int pt)
{
    if(ps>pt) return ;
    else if(ps==pt)
    {
        if(str[ps]=='('||str[ps]==')') printf("()");
        else printf("[]");
    }
    else if(mark[ps][pt]==-1)
    {
        printf("%c", str[ps]);
        out(ps+1, pt-1);
        printf("%c", str[pt]);
    }
    else
    {
        out(ps, mark[ps][pt]);
        out(mark[ps][pt]+1, pt);
    }
}
int main()
{
    int i;
    while(gets(str)!=NULL)
    {
        n=strlen(str);
        solve();
        out(0, n-1);
        printf("\n");
    }
    return 0;
}