POJ 1141 输出正确的括号匹配(最少添加)

Brackets Sequence

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 32174   Accepted: 9291   Special Judge

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

()[()]

在上面那个NYoj的基础上添加打印,打印的时候重新检查一下哪个决策最好。好处是节约空间,坏处是打印时代码浮渣,速度稍慢,但是基本上可以忽略不计,因为只有少数状态需要打印。注意要gets读入,有空串的情况。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1000+10;
int dp[maxn][maxn];
char str[maxn];
int n;
bool match(char a,char b) {
    if( a==‘(‘&&b==‘)‘||a==‘[‘&&b==‘]‘ )
        return true;
    else
        return false;
    }
void solve() {
    for(int i = 0; i < n; i++) {
        dp[i+1][i] = 0;
        dp[i][i] = 1;
    }

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

        }
    }
}

void print(int i,int j) {
    if(i>j) return ;
    if(i==j){
       if(str[i]==‘(‘||str[i]==‘)‘ )
            printf("()");
       else
        printf("[]");
       return;
    }
    int ans = dp[i][j];
    if(match(str[i],str[j]) && ans==dp[i+1][j-1]) {
        printf("%c",str[i]);
        print(i+1,j-1);
        printf("%c",str[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()
{
//    freopen("in.txt","r",stdin);
//    int T;
//    scanf("%d",&T);
//    getchar();
    while(gets(str)) {
        n = strlen(str);
        solve();
        print(0,n-1);
        printf("\n");
    }
    return 0;
}
时间: 2025-01-14 14:45:58

POJ 1141 输出正确的括号匹配(最少添加)的相关文章

POJ 2955 Brackets (区间dp 括号匹配)

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3951   Accepted: 2078 Description We give the following inductive definition of a "regular brackets" sequence: the empty sequence is a regular brackets sequence, if s is a reg

POJ 1141-Brackets Sequence(区间dp括号匹配打印路径)

题目地址:POJ 1141 题意:给出一串由'(')'' [ ' ' ] '组成的串,将给出的括号序列以添加最小数目括号的形式进行配对. 思路:dp[i][j]表示当前子序列需要添加的最小字符数,path存储的是所有子问题的解.然后详情看代码解释. #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #in

poj 2955 区间dp(括号匹配)

#include<stdio.h> #include<string.h> #include<iostream> using namespace std; int max(int a,int b) { return a>b?a:b; } int main() { char str[110]; int dp[110][110]; int i,j; while(~scanf("%s",str)) { int len=strlen(str); if(s

水了两道括号匹配

POJ 1141 给一段括号序列,要求增加最少的括号,使之合法,输出序列. dp[i][j]表示使给定序列的i到j成为合法序列所需添加的最少括号数,dp[0][length-1]即是答案,转移的话,如果s[i]和s[j]可以匹配那么dp[i][j] = dp[i+1][j-1],否则就考虑在中间选择一个位置m,使分割成的两个序列各自成为合法序列.方案的话就是多开一个数组记录然后递归输出.状态是从长度小的序列转移到长度长的序列,所以两层循环,外层枚举长度,内层枚举头位置即可.写成记忆化搜索简单一点

POJ C程序设计进阶 编程题#4:括号匹配问题

编程题#4:扩号匹配问题 来源: POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 在某个字符串(长度不超过100)中有左括号.右括号和大小写字母:规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配.写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号.不能匹配的左括号用"$"标注,不能匹配的右括号用&quo

poj 2955 Brackets 括号匹配 区间dp

题意:最多有多少括号匹配 思路:区间dp,模板dp,区间合并. 对于a[j]来说: 刚開始的时候,转移方程为dp[i][j]=max(dp[i][j-1],dp[i][k-1]+dp[k][j-1]+2), a[k]与a[j] 匹配,结果一组数据出错 ([]]) 检查的时候发现dp[2][3]==2,对,dp[2][4]=4,错了,简单模拟了一下发现,dp[2][4]=dp[2][1]+dp[2][3]+2==4,错了 此时2与4已经匹配,2与3已经无法再匹配. 故转移方程改为dp[i][j]=

Brackets Sequence POJ - 1141 (区间dp)

Brackets Sequence POJ - 1141 题意:给一个括号序列,问最少添加多少个括号似的原序列匹配,并输出新序列. 用dp[i][j]表示i到j最少添加几个括号,flag[i][j]表示i和j之间需要添加括号的位置. 1 #include<cstdio> 2 #include<algorithm> 3 #include<string> 4 #include<iostream> 5 #include <cstdlib> 6 #inc

POJ 1141 Brackets Sequence (区间dp 记录路径)

题目大意: 给出一种不合法的括号序列,要求构造出一种合法的序列,使得填充的括号最少. 思路分析: 如果只要求输出最少的匹配括号的数量,那么就是简单的区间dp dp[i][j]表示 i - j 之间已经合法了最少添加的括号数. 转移 就是 dp[i] [j] = min  (dp[i+1][j]+1 , dp[ i+ 1] [ k -1 ] + dp[k+1] [j] (i k 位置的括号匹配)) 其次我们要记录路径,你发现  如果 dp [i] [j] 是由 dp [i+1] [j] 转移过来的

[ACM] POJ 1141 Brackets Sequence (区间动态规划)

Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 25087   Accepted: 7069   Special Judge Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a regular sequence. 2. If S is a re