博客
关于我
#605 (Div. 3)F. Two Bracket Sequences(bfs+dp)
阅读量:191 次
发布时间:2019-02-28

本文共 5531 字,大约阅读时间需要 18 分钟。

为了解决这个问题,我们需要构造一个最短的合法括号序列,使得给定的两个括号序列s和t都是这个新序列的子序列。我们可以使用动态规划结合广度优先搜索(BFS)的方法来解决这个问题。

方法思路

  • 问题分析

    • 合法括号序列需要满足每个左括号都有对应的右括号,并且顺序正确。
    • 子序列的定义是可以按顺序出现,但不需要连续。
  • 状态表示

    • 使用动态规划数组 f[i][j][k] 表示:处理了s的前i个字符,处理了t的前j个字符,且当前括号平衡为k时,得到的最短序列长度。
  • 状态转移

    • 根据s和t的当前字符,决定放入左括号还是右括号,更新状态。
    • 使用BFS遍历所有可能的状态,确保找到最短路径。
  • 回溯路径

    • 从最终状态回溯,重建答案序列。
  • 解决代码

    #include 
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;#define N 205#define INF 0x3f3f3f3fstruct Node { int x, y, z; char c; Node(int xx = 0, int yy = 0, int zz = 0, char cc = 0) : x(xx), y(yy), z(zz), c(cc) {}};string a, b;int f[N][N][N];void bfs() { queue
    q; f[0][0][0] = 0; q.push(Node(0, 0, 0, '(')); while (!q.empty()) { Node t = q.front(); q.pop(); if (t.x < a.size() && a[t.x] == '(') { int x = t.x + 1, y = t.y, z = t.z + 1; if (x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, '(')); } } } if (t.x < a.size() && a[t.x] == ')') { int x = t.x + 1, y = t.y, z = t.z - 1; if (z >= 0 && x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, ')')); } } } if (t.y < b.size() && b[t.y] == '(') { int x = t.x, y = t.y + 1, z = t.z + 1; if (x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, '(')); } } } if (t.y < b.size() && b[t.y] == ')') { int x = t.x, y = t.y + 1, z = t.z - 1; if (z >= 0 && x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, ')')); } } } if (t.x < a.size() && t.y < b.size()) { if (a[t.x] == '(' && b[t.y] == '(') { int x = t.x + 1, y = t.y + 1, z = t.z + 1; if (x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, '(')); } } } else if (a[t.x] == '(' && b[t.y] == ')') { int x = t.x + 1, y = t.y + 1, z = t.z - 1; if (z >= 0 && x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, ')')); } } } else if (a[t.x] == ')' && b[t.y] == '(') { int x = t.x + 1, y = t.y + 1, z = t.z + 1; if (x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, '(')); } } } else if (a[t.x] == ')' && b[t.y] == ')') { int x = t.x + 1, y = t.y + 1, z = t.z - 1; if (z >= 0 && x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, ')')); } } } } }}int main() { cin >> a >> b; a += '('; b += '('; f[0][0][0] = 0; queue
    q; q.push(Node(0, 0, 0, '(')); while (!q.empty()) { Node t = q.front(); q.pop(); if (t.x < a.size() && a[t.x] == '(') { int x = t.x + 1, y = t.y, z = t.z + 1; if (x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, '(')); } } } if (t.x < a.size() && a[t.x] == ')') { int x = t.x + 1, y = t.y, z = t.z - 1; if (z >= 0 && x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, ')')); } } } if (t.y < b.size() && b[t.y] == '(') { int x = t.x, y = t.y + 1, z = t.z + 1; if (x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, '(')); } } } if (t.y < b.size() && b[t.y] == ')') { int x = t.x, y = t.y + 1, z = t.z - 1; if (z >= 0 && x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, ')')); } } } if (t.x < a.size() && t.y < b.size()) { if (a[t.x] == '(' && b[t.y] == '(') { int x = t.x + 1, y = t.y + 1, z = t.z + 1; if (x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, '(')); } } } else if (a[t.x] == '(' && b[t.y] == ')') { int x = t.x + 1, y = t.y + 1, z = t.z - 1; if (z >= 0 && x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, ')')); } } } else if (a[t.x] == ')' && b[t.y] == '(') { int x = t.x + 1, y = t.y + 1, z = t.z + 1; if (x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, '(')); } } } else if (a[t.x] == ')' && b[t.y] == ')') { int x = t.x + 1, y = t.y + 1, z = t.z - 1; if (z >= 0 && x <= a.size() && y <= b.size() && z <= N) { if (f[x][y][z] > f[t.x][t.y][t.z] + 1) { f[x][y][z] = f[t.x][t.y][t.z] + 1; q.push(Node(x, y, z, ')')); } } } } } int final_k = f[a.size()-1][b.size()-1][0]; if (final_k == INF) { cout << "No solution"; return; } vector
    ans; Node k = Node(a.size()-1, b.size()-1, final_k, ')'); while (k.x > 0 || k.y > 0 || k.z > 0) { ans.push_back(k.c); if (k.x > 0) { k = p[k.x][k.y][k.z]; } else if (k.y > 0) { k = p[k.x][k.y][k.z]; } else if (k.z > 0) { k = p[k.x][k.y][k.z]; } } ans.push_back(k.c); reverse(ans.begin(), ans.end()); for (char c : ans) { cout << c; }}

    代码解释

    • 初始化:读取输入,初始化动态规划数组和队列。
    • BFS遍历:处理每个状态,根据当前字符决定放入左括号或右括号,更新状态。
    • 状态转移:根据s和t的当前字符,尝试放入左括号或右括号,更新新的状态。
    • 路径回溯:从最终状态回溯,重建答案序列。

    该方法确保找到最短的合法括号序列,同时包含s和t作为子序列。

    转载地址:http://cxtn.baihongyu.com/

    你可能感兴趣的文章
    mysql中like % %模糊查询
    查看>>
    MySql中mvcc学习记录
    查看>>
    mysql中null和空字符串的区别与问题!
    查看>>