1272F

dp

$dp[i][j][k]$表示第一个串匹配到$i$,第二个串匹配到$j$,前缀和为$k$

由于前缀和不会超过$n$,所以直接$bfs$转移即可

输出方案记录$dp$前继即可

时间复杂度$O(n^3)$

#include <bits/stdc++.h>
using namespace std;
const int maxn = 205;
struct node {
    int a, b, c;
    node() = default;
    node(int _a, int _b, int _c) : a(_a), b(_b), c(_c) {}
};
int dp[maxn][maxn][maxn], pre[maxn][maxn][maxn];
char s[maxn], t[maxn];
int H(int a, int b, int c) {
    return a * 1000 * 1000 + b * 1000 + c;
}
node D(int h) {
    return node(h / 1000000, (h / 1000) % 1000, h % 1000);
}
int main() {
    scanf("%s%s", s + 1, t + 1);
    int n = strlen(s + 1), m = strlen(t + 1);
    s[n + 1] = '?';
    t[m + 1] = '?';
    queue<node> q;
    q.push(node(0, 0, 0));
    memset(dp, -1, sizeof(dp));
    dp[0][0][0] = 0;
    while(!q.empty()) {
        auto u = q.front();
        q.pop();
        int a = u.a + (s[u.a + 1] == ')');
        int b = u.b + (t[u.b + 1] == ')');
        int c = u.c - 1;
        if(c >= 0 && dp[a][b][c] == -1) {
            dp[a][b][c] = dp[u.a][u.b][u.c] + 1;
            pre[a][b][c] = H(u.a, u.b, u.c);
            q.push(node(a, b, c));
        }
        a = u.a + (s[u.a + 1] == '(');
        b = u.b + (t[u.b + 1] == '(');
        c = u.c + 1;
        if(c <= 200 && dp[a][b][c] == -1) {
            dp[a][b][c] = dp[u.a][u.b][u.c] + 1;
            pre[a][b][c] = H(u.a, u.b, u.c);
            q.push(node(a, b, c));
        }
    }
    vector<char> ans;
    int a = n, b = m, c = 0;
    for(int i = 0; i < dp[n][m][0]; ++i) {
        node t = D(pre[a][b][c]);
        if(c == t.c + 1) {
            ans.push_back('(');
        } else {
            ans.push_back(')');
        }
        a = t.a;
        b = t.b;
        c = t.c;
    }
    for(int i = ans.size() - 1; ~i; --i) {
        printf("%c", ans[i]);
    }
    return 0;
}
View Code

 

posted @ 2019-12-17 18:37  19992147  阅读(148)  评论(0编辑  收藏  举报