POJ 1141 Brackets Sequence (区间DP)

Posted yutingliuyl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1141 Brackets Sequence (区间DP)相关的知识,希望对你有一定的参考价值。

Description

Let us define a regular brackets sequence in the following way:

1. Empty sequence is a regular sequence.
2. If S is a regular sequence, then (S) and [S] are both regular sequences.
3. If A and B are regular sequences, then AB is a regular sequence.

For example, all of the following sequences of characters are regular brackets sequences:

(), [], (()), ([]), ()[], ()[()]

And all of the following character sequences are not:

(, [, ), )(, ([)], ([(]

Some sequence of characters ‘(‘, ‘)‘, ‘[‘, and ‘]‘ is given. You are to find the shortest possible regular brackets sequence, that contains the given character sequence as a subsequence. Here, a string a1 a2 ... an is called a subsequence of the string b1 b2 ... bm, if there exist such indices 1 = i1 < i2 < ... < in = m, that aj = bij for all 1 = j = n.

Input

The input file contains at most 100 brackets (characters ‘(‘, ‘)‘, ‘[‘ and ‘]‘) that are situated on a single line without any other characters among them.

Output

Write to the output file a single line that contains some regular brackets sequence that has the minimal possible length and contains the given sequence as a subsequence.

Sample Input

([(]

Sample Output

()[()]


题意:给一串括号序列。依照合法括号的定义,加入若干括号,使得序列合法。

典型区间DP。设dp[i][j]为从i到j须要加入最少括号的数目。

dp[i][j] = max{ dp[i][k]+dp[k+1][j] }  (i<=k<j)

假设s[i] == s[j] , dp[i][j] 还要和dp[i+1][j-1]比較。 枚举顺序依照区间长度枚举。

由于要求输出合法序列,就要记录在原序列在哪些位置进行了添加,设c[i][j]为从i到j的 添加括号的位置,假设不须要添加。那么c[i][j] 赋为-1,打印时仅仅需递归打印就可以。


#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long LL;
const int MAX=0x3f3f3f3f;
int n,c[105][105],dp[105][105];
char s[105];
void print(int i,int j) {
    if( i>j ) return ;
    if( i == j ) {
        if(s[i] == '(' || s[i] == ')') printf("()");
        else printf("[]");
        return ;
    }
    if( c[i][j] > 0 ) {  // i到j存在添加括号的地方,位置为c[i][j]
        print(i,c[i][j]);
        print(c[i][j]+1,j);
    } else {
        if( s[i] == '(' ) {
            printf("(");
            print(i+1,j-1);
            printf(")");
        } else {
            printf("[");
            print(i+1,j-1);
            printf("]");
        }
    }
}
void DP() {   //区间DP
    for(int len=2;len<=n;len++)
        for(int i=1;i<=n-len+1;i++) {
            int j = i+len-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];
                c[i][j] = k;  // 记录断开的位置
            }
            if( ( s[i] == '(' && s[j] == ')' || s[i] == '[' && s[j] == ']' ) && dp[i][j] > dp[i+1][j-1] ) {
                dp[i][j] = dp[i+1][j-1];
                c[i][j] = -1;  //i到j不须要断开。由于dp[i+1][j-1]的值更小,上面枚举的k位置都比这个大。所以不再断开
            }
        }
}
int main()
{
    scanf("%s",s+1);
    n = strlen(s+1);
    memset(c,-1,sizeof(c));
    memset(dp,MAX,sizeof(c));
    for(int i=1;i<=n;i++) dp[i][i] = 1, dp[i][i-1] = 0; //赋初值
    DP();
    print(1,n);
    printf("\n");
    return 0;
}





以上是关于POJ 1141 Brackets Sequence (区间DP)的主要内容,如果未能解决你的问题,请参考以下文章

POJ1141 Brackets Sequence

POJ 1141 Brackets Sequence

poj 1141 Brackets Sequence

POJ 1141 —— Brackets Sequence

POJ 1141 Brackets Sequence (区间DP)

poj 1141 Brackets Sequence (区间DP)