POJ 1141 - Brackets Sequence


http://poj.org/problem?id=1141
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
()[()]
思路和POJ 2955是类似的。我们用DP[i][j]表示把子串s[i, j]补完成合法序列所需要的最少的字符数。我们有递推公式:

  • DP[i][j] = D[i + 1][j],如果s[i]在s[i + 1, j]中没有括号与之match
  • DP[i][j] = max(dp[i + 1][k - 1] + dp[k + 1][j]),如果s[i]和s[k]match
但是这个公式只能算出最少需要补完多少个字符来使之合法。我们还需要记录打印结果的路径(只打印满足条件的一个即可),我们用path[i][j]来记录s[i,j]的分割点,如果s[i]没有match,path[i][j] = -1;如果s[i]和s[k]match且其使得需要补完的char数最少,path[i][j] = k。我们打印的时候根据path自上而下递归地打印即可,详细可以参见代码中的print方法。时间复杂度空间复杂度均为O(n^2)

int dp[MAX][MAX], path[MAX][MAX];
char s[MAX];

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

int main()
{
    while(gets(s))
    {
        int len = strlen(s);
        if(len == 0)
        {
            printf("\n");
            continue;
        }
        memset(dp, 0, sizeof(dp[0][0] * MAX * MAX));
        memset(path, 0, sizeof(path[0][0] * MAX * MAX));
        for(int i = 0; i < len; ++i)dp[i][i] = 1;
        for(int j = 0; j < len; ++j)
        {
            for(int i = j - 1; i >= 0; --i)
            {
                //assume s[i] doesn't match
                dp[i][j] = dp[i + 1][j] + 1;
                path[i][j] = -1;
                for(int k = i + 1; k <= j; ++k)
                {
                    if(s[i] == '(' && s[k] == ')' || s[i] == '[' && s[k] == ']')
                    {
                        int cost = dp[i + 1][k - 1] + dp[k + 1][j];
                        if(cost < dp[i][j])
                        {
                            dp[i][j] = cost;
                            path[i][j] = k;//s[k] matches s[i]
                        }
                    }
                }
            }
        }
        print(0, len - 1);
        printf("\n");
    }

简单区间dp,对于一段区间,分三种情况讨论:
1、这个区间被分成多块。(regular sequence算是一块)
2、整个是一块,且两边分别保留一个字符。
3、整个是一块,且只保留一边的一个字符。
题意:添加最少的符号,使得它是完美的。

思路:用dp[i][j]表示修i到j需要的最少符号数量
解题思路:与POJ 2955 Brackets这题一样,是一个区间DP的题。思想很类似,但有些许差异。设dp[l][r]表示区间[l,r]内至少需要增加的括号数,则状态转移如下:
1、l==r时,dp[l][r]显然为1;
2、l与r匹配时,dp[l][r] = min(dp[l][r], dp[l+1][r-1]);
3、l与r不匹配时,可将区间[l,r]分成两个区间[l,mid]和[mid+1,r],其中l<=mid<r。
注意:不管上述2是否满足,都要去尝试上述3,否则就会出现"[][]"转移到"]["的情况,这样就只能够添加两个括号了。还有一个注意点就是,当l>r时,要更新dp[l][r]=0,否则在输出结果时,类似"[][]"的结果输不出来,因为不符合判断条件。详见代码。

 5 const int maxn = 105;
 6 const int inf = 0x3f3f3f3f;
 7 char str[maxn];
 8 int dp[maxn][maxn];
 9 
10 bool match(char a, char b){
11     return (a=='('&&b==')') || (a=='['&&b==']');
12 }
13 
14 int dfs(int l, int r){
15     if (l > r)
16         return dp[l][r] = 0;
17     if (l == r)
18         return dp[l][r] = 1;
19     if (dp[l][r] != inf)
20         return dp[l][r];
21     int ans = dp[l][r];
22     if (match(str[l], str[r]))
23         ans = min(ans, dfs(l+1, r-1));
24     for (int i=l; i<r; ++i)
25         ans = min(ans, dfs(l, i)+dfs(i+1, r));
26     return dp[l][r] = ans;
27 }
28 
29 void print(int l, int r){
30     if (l > r)
31         return ;
32     if (l == r){
33         if (str[l]=='(' || str[r]==')')
34             printf("()");
35         else
36             printf("[]");
37         return ;
38     }
39     int ans = dp[l][r];
40     if (match(str[l], str[r]) && ans==dp[l+1][r-1]){
41         putchar(str[l]);
42         print(l+1, r-1);
43         putchar(str[r]);
44         return ;
45     }
46     for (int i=l; i<r; ++i)
47         if (ans == dp[l][i]+dp[i+1][r]){
48             print(l, i);
49             print(i+1, r);
50             return ;
51         }
52 }

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts