博客
关于我
#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/

    你可能感兴趣的文章
    mysqldump 导出数据库中每张表的前n条
    查看>>
    mysqldump: Got error: 1044: Access denied for user ‘xx’@’xx’ to database ‘xx’ when using LOCK TABLES
    查看>>
    Mysqldump参数大全(参数来源于mysql5.5.19源码)
    查看>>
    mysqldump备份时忽略某些表
    查看>>
    mysqldump实现数据备份及灾难恢复
    查看>>
    mysqldump数据库备份无法进行操作只能查询 --single-transaction
    查看>>
    mysqldump的一些用法
    查看>>
    mysqli
    查看>>
    MySQLIntegrityConstraintViolationException异常处理
    查看>>
    mysqlreport分析工具详解
    查看>>
    MySQLSyntaxErrorException: Unknown error 1146和SQLSyntaxErrorException: Unknown error 1146
    查看>>
    Mysql_Postgresql中_geometry数据操作_st_astext_GeomFromEWKT函数_在java中转换geometry的16进制数据---PostgreSQL工作笔记007
    查看>>
    mysql_real_connect 参数注意
    查看>>
    mysql_secure_installation初始化数据库报Access denied
    查看>>
    MySQL_西安11月销售昨日未上架的产品_20161212
    查看>>
    Mysql——深入浅出InnoDB底层原理
    查看>>
    MySQL“被动”性能优化汇总
    查看>>
    MySQL、HBase 和 Elasticsearch:特点与区别详解
    查看>>
    MySQL、Redis高频面试题汇总
    查看>>
    MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
    查看>>