zoukankan      html  css  js  c++  java
  • 1626

    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 a1a2...an is called a subsequence of the string b1b2...bm, if there exist such indices 1 ≤ i1 < i2 < ... < in ≤ m, that aj=bij for all 1 ≤ j ≤ n.

    Input 

    The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs.

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

    Output 

    For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line.

    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 

    1
    
    ([(]
    

    Sample Output 

    ()[()]


    紫书上有详解+代码,就不废话了直接贴代码:
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 const int maxn = 110;
     6 char s[maxn];
     7 int d[maxn][maxn];
     8 int n;
     9 inline bool match(char a,char b){
    10     if((a=='('&&b==')')||(a=='['&&b==']')) return true;
    11     else return false;
    12 }
    13 void dp(){
    14     for(int i=0;i<n;i++){
    15         d[i+1][i]=0;
    16         d[i][i]=1;
    17     }
    18    
    19     for(int i=n-2;i>=0;i--){
    20         for(int j=i+1;j<n;j++){
    21             d[i][j]=maxn;
    22             if(match(s[i],s[j]))
    23                 d[i][j]=min(d[i][j],d[i+1][j-1]);
    24             for(int k=i;k<j;k++){
    25                 d[i][j]=min(d[i][j],d[i][k]+d[k+1][j]);
    26             }
    27         }
    28     }
    29 }
    30 void print(int i,int j){
    31     if(i>j) return;
    32     if(i==j){
    33         if(s[i]=='('||s[i]==')') printf("()");
    34         else printf("[]");
    35         return;
    36     }
    37     int ans=d[i][j];
    38     if(match(s[i],s[j])&&ans==d[i+1][j-1]){
    39         printf("%c",s[i]);print(i+1,j-1);printf("%c",s[j]);
    40         return;
    41     }
    42     for(int k=i;k<j;k++){
    43         if(ans==d[i][k]+d[k+1][j]){
    44             print(i,k);print(k+1,j);
    45             return;
    46         }
    47     }
    48     
    49 }
    50 int main(int argc, const char * argv[]) {
    51     int T;
    52     scanf("%d",&T);
    53     getchar();
    54     while(T--){
    55         getchar();
    56         memset(s, 0, sizeof s);
    57         char ch;
    58         for(int i=0;(ch=getchar())!='
    ';i++){
    59             s[i]=ch;
    60         }
    61         n=strlen(s);
    62         
    63         dp();
    64         print(0,n-1);
    65         printf("
    ");
    66         if(T!=0) printf("
    ");
    67     }
    68     return 0;
    69 }
  • 相关阅读:
    vue自定义指令,自动调用下载的方法
    electron桌面通知,修改默认通知应用名electron.app.Electron为自己应用的名称
    C++二叉树前中后序遍历(递归&非递归)统一代码格式
    反转链表和反转链表2
    基于partition的递归
    C++归并排序(数组&链表)
    关于C++跨平台
    Visual Studio 2019社区版:错误 MSB6006 “CL.exe”已退出,代码为 2
    腾讯2017校招开发工程师笔试试卷(一)答题解析
    C++面试高频题
  • 原文地址:https://www.cnblogs.com/Kiraa/p/5516125.html
Copyright © 2011-2022 走看看