POJ1141-Brackets Sequence【DP思想+递归】

题解: dp [ i ] [ j ] 表示添加括号的个数, pos[ i][ j ] 表示 i , j 中哪个位置分开,使得两部分分别匹配。
pos [ i ][ j ] 为-1的时候,说明i, j 括号匹配。
初始值置dp [ i ] [ i ] = 1; 如果只有一个括号,那么匹配结果必然是差1。
首先判断括号是否匹配,如果匹配,那么dp [ i ] [ j ] = dp[ i + 1] [ j - 1] 。如此递推dp [ i ] [ j ] 的值。
然后判断dp [ i ] [ j ] = min ( dp [ i ] [ mid ] + dp [ mid + 1 ] [ j ]);
输出结果时采用递归方式输出print(0, len-1)

输出函数定义为print(int i, int j),表示输出从下标i到下标j的合法序列

当i>j时,直接返回,不需要输出

当i==j时,d[i][j]为1,至少要加一个括号,如果s[i]为’(’ 或者’)’,输出"()",否则输出"[]"

当i>j时,如果c[i][j]>=0,说明从i到j断开了,则递归调用print(i, c[i][j]);和print(c[i][j]+1,j);
如果c[i][j]<0,说明没有断开,如果s[i]==’(’ 则输出’(’、 print(i+1, j-1); 和")",否则输出"[" print(i+1, j-1);和"]"

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=105;
char str[maxn];
int dp[maxn][maxn];
int path[maxn][maxn];

void oprint(int i,int j)
{
    if(i>j)
        return;
    if(i==j)
    {
        if(str[i]=='['||str[i]==']')
        {
            printf("[]");
        }
        else
        {
            printf("()");
        }
    }
    else if(path[i][j]==-1)
    {
        printf("%c",str[i]);
        oprint(i+1,j-1);
        printf("%c",str[j]);
    }
    else
    {
        oprint(i,path[i][j]);
        oprint(path[i][j]+1,j);
    }
}

int main()
{
    while(gets(str))
    {
        int n=strlen(str);
        memset(dp,0,sizeof(dp));
        if(n==0)
        {
            printf("\n");
            continue;
        }
        for(int i=0; i<n; i++)
        {
            dp[i][i]=1;
        }
        for(int r=1; r<n; r++)
        {
            for(int i=0; i<n-r; i++)
            {
                int j=i+r;
                dp[i][j]=0x7fffffff;
                if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))
                {
                    dp[i][j]=dp[i+1][j-1];
                    path[i][j]=-1;
                }
                for(int 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];
                        path[i][j]=k;
                    }
                }

            }
        }
        oprint(0,n-1);
        printf("\n");
    }
}

猜你喜欢

转载自blog.csdn.net/Li_Hongcheng/article/details/86675465