zoukankan      html  css  js  c++  java
  • 【cf1272】F. Two Bracket Sequences

    传送门

    题意:
    给出(s,t)两个合法括号序列,现在找到一个长度最小的合法的序列(p),使得(s,t)都为其子序列。

    思路:

    • 考虑(dp:dp[i][j][d])表示第一个串在(i),第二个串在(j),答案串左括号和右括号之差为(d)时的最短长度。
    • 那么转移时枚举下一位转移即可。
    • 还需要考虑一点细节:若当前(d=0),但是下一位为)时,我们需要先(dp[i][j][0])(dp[i][j][1])转移,即在答案串中添加一个(来匹配。
    • 最后的答案即为(min{dp[n][m][d]+d}),若(d>0)时,我们还需要在答案串后面添加(d)个)来使其合法。
    • 输出路径时转移时记录一下前驱,然后根据(d)来找到当前应为哪个括号。

    代码如下:

    /*
     * Author:  heyuhhh
     * Created Time:  2019/12/13 11:40:50
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #define MP make_pair
    #define fi first
    #define se second
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    void pt() {std::cout << '
    '; }
    template<typename T, typename...Args>
    void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 200 + 5;
     
    struct node {
        int i, j, k;   
    };
     
    node pre[N][N][N << 1];
    int dp[N][N][N << 1];
    int n, m;
    char s[N], t[N];
     
    void run(){
        cin >> (s + 1) >> (t + 1);
        n = strlen(s + 1);
        m = strlen(t + 1);
        memset(dp, INF, sizeof(dp));
        dp[0][0][0] = 0;
        for(int i = 0; i <= n; i++) {
            for(int j = 0; j <= m; j++) {
                if(i == n && j == m) break;
                for(int k = 0; k < N; k++) if(dp[i][j][k] != INF) {
                    if(s[i + 1] == t[j + 1]) {
                        if(s[i + 1] == ')') {
                            if(k == 0) {
                                if(dp[i][j][k + 1] > dp[i][j][k] + 1) {
                                    dp[i][j][k + 1] = dp[i][j][k] + 1;
                                    pre[i][j][k + 1] = node {i, j, k};   
                                }
                            } 
                            if(dp[i + 1][j + 1][k - 1] > dp[i][j][k] + 1) {
                                dp[i + 1][j + 1][k - 1] = dp[i][j][k] + 1;
                                pre[i + 1][j + 1][k - 1] = node {i, j, k};   
                            }
                        } else if(s[i + 1] == '(') {
                            if(dp[i + 1][j + 1][k + 1] > dp[i][j][k] + 1) {
                                dp[i + 1][j + 1][k + 1] = dp[i][j][k] + 1;
                                pre[i + 1][j + 1][k + 1] = node {i, j, k};
                            }   
                        }
                    } else {
                        if(s[i + 1] == ')') {
                            if(k == 0) {
                                if(dp[i][j][k + 1] > dp[i][j][k] + 1) {
                                    dp[i][j][k + 1] = dp[i][j][k] + 1;
                                    pre[i][j][k + 1] = node {i, j, k};
                                }   
                            }
                            if(dp[i + 1][j][k - 1] > dp[i][j][k] + 1) {
                                dp[i + 1][j][k - 1] = dp[i][j][k] + 1;
                                pre[i + 1][j][k - 1] = node {i, j, k};   
                            }
                        } else if(s[i + 1] == '(') {
                            if(dp[i + 1][j][k + 1] > dp[i][j][k] + 1) {
                                dp[i + 1][j][k + 1] = dp[i][j][k] + 1;
                                pre[i + 1][j][k + 1] = node {i, j, k};
                            }   
                        }  
                        if(t[j + 1] == ')') {
                            if(k == 0) {
                                if(dp[i][j][k + 1] > dp[i][j][k] + 1) {
                                    dp[i][j][k + 1] = dp[i][j][k] + 1;
                                    pre[i][j][k + 1] = node {i, j, k};
                                }  
                            }
                            if(dp[i][j + 1][k - 1] > dp[i][j][k] + 1) {
                                dp[i][j + 1][k - 1] = dp[i][j][k] + 1;
                                pre[i][j + 1][k - 1] = node {i, j, k};   
                            }
                        } else if(t[j + 1] == '(') {
                            if(dp[i][j + 1][k + 1] > dp[i][j][k] + 1) {
                                dp[i][j + 1][k + 1] = dp[i][j][k] + 1;
                                pre[i][j + 1][k + 1] = node {i, j, k};
                            }   
                        }
                    }
                }
            }   
        }
        int Min = INF;
        node ans;
        for(int i = 0; i < N; i++) {
            if(dp[n][m][i] + i < Min) {
                Min = dp[n][m][i] + i;
                ans = node {n, m, i};   
            }
        }
        //for(int i = 400; i < 410; i++) {
            //cout << dp[1][3][i] << '
    ';   
        //}
        string res = "";
        node now = ans, last;
        while(1) {
             last = pre[now.i][now.j][now.k];
             //dbg(now.i, now.j, now.k, dp[now.i][now.j][now.k]);
             if(last.k > now.k) res += ")";
             else res += "(";
             now = last;
             if(now.i == 0 && now.j == 0 && now.k == 0) break;
        }
        reverse(res.begin(), res.end());
        for(int i = 0; i < ans.k; i++) res += ")";
        cout << res << '
    ';;
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    
  • 相关阅读:
    [LeetCode] 60. Permutation Sequence 序列排序
    [LeetCode] 31. Next Permutation 下一个排列
    [LeetCode] 47. Permutations II 全排列 II
    [LeetCode] 46. Permutations 全排列
    [LeetCode] 77. Combinations 全组合
    利用 Json.Net 将对象转换成Json
    使用sqlmetal工具自动生成SQL数据库的Linq类文件
    SharePoint 2013 设置 显示详细错误信息 修改位置总结
    本地访问Vmware虚机Web网站
    Web项目HttpContext.Current 为空
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/12043634.html
Copyright © 2011-2022 走看看