poj 1141 Brackets Sequence(区间dp+回溯)

题目:

Brackets Sequence的题目链接

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 34409   Accepted: 9949   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

()[()]

题目大意:

括号匹配问题,要求补全后的字符串长度最短。

思路:

通过区间dp来记录当前最优解,通过取断点来记录当前最少添加括号数,通过一个path数组来记录括号的匹配路径。最后回溯一遍输出匹配好的括号串就ok了。

状态转移方程:dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j])

AC代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
const int N = 207;
const int inf = 0x3f3f3f3f;
char a[N];
int dp[N][N],len,path[N][N];
void init()
{
    for(int i = 0;i < N;++i)
        for(int j = 0;j < N;++j)
            dp[i][j] = i == j ? 1 : 0;
    memset(path,0,sizeof path);
    len = strlen(a);
}
bool judge(int i,int j)//判断括号是否匹配
{
    if((a[i] == '(' && a[j] == ')') || (a[i] == '[' && a[j] == ']')) return true;
    return false;
}
void print_dfs(int i,int j)
{
    if(i > j) return ;
    else if(i == j){
        if(a[i] == '(' || a[i] == ')') printf("()");
        else if(a[i] == '[' || a[i] == ']') printf("[]");
    }
    else if(path[i][j] == -1){
        printf("%c",a[i]);
        print_dfs(i + 1,j - 1);
        printf("%c",a[j]);
    }
    else{
        print_dfs(i,path[i][j]);
        print_dfs(path[i][j] + 1,j);
    }
}
int main()
{
    while(gets(a) != NULL){
        init();
        for(int l = 1;l < len;++l){
            for(int i = 0;i + l < len;++i){
                int j = i + l;
                dp[i][j] = inf;
                if(judge(i,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;
                    }
                }
            }
        }
        print_dfs(0,len - 1);//回溯路径
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41791981/article/details/82216690
今日推荐