博客
关于我
#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 学习总结(87)—— Mysql 执行计划(Explain)再总结
    查看>>
    Mysql 学习总结(88)—— Mysql 官方为什么不推荐用雪花 id 和 uuid 做 MySQL 主键
    查看>>
    Mysql 学习总结(89)—— Mysql 库表容量统计
    查看>>
    mysql 实现主从复制/主从同步
    查看>>
    mysql 审核_审核MySQL数据库上的登录
    查看>>
    mysql 导入 sql 文件时 ERROR 1046 (3D000) no database selected 错误的解决
    查看>>
    mysql 导入导出大文件
    查看>>
    mysql 将null转代为0
    查看>>
    mysql 常用
    查看>>
    MySQL 常用列类型
    查看>>
    mysql 常用命令
    查看>>
    Mysql 常见ALTER TABLE操作
    查看>>
    MySQL 常见的 9 种优化方法
    查看>>
    MySQL 常见的开放性问题
    查看>>
    Mysql 常见错误
    查看>>
    MYSQL 幻读(Phantom Problem)不可重复读
    查看>>
    mysql 往字段后面加字符串
    查看>>
    mysql 快速自增假数据, 新增假数据,mysql自增假数据
    查看>>
    Mysql 报错 Field 'id' doesn't have a default value
    查看>>
    MySQL 报错:Duplicate entry 'xxx' for key 'UNIQ_XXXX'
    查看>>