Codeforces 1272F. Two Bracket Sequences(BFS+DP+路径记忆)

53 篇文章 1 订阅
13 篇文章 1 订阅

Codeforces Round #605 (Div. 3) 题解全文见: https://blog.csdn.net/qq_43461168/article/details/114377042

F. Two Bracket Sequences

题意:给出两个括号串,求一个最短的括号串,使得这两个串都是他的子序列。

思路:参考官方题解。BFS+DP。用dp[i][j][d]表示包含s1的前i个,s2的前j个,且度为d的情况下的最小长度。 度定义为 左括号的数量-右括号的数量。转移呢,肯定是从 dp[0][0][0]开始。然后如果填入一个左括号,那么d += 1。并且如果s1[i] == ‘(’,那么 i+=1,同理如果 s2[j] == ‘(’,j += 1。右括号同理。且在dp 的过程中,要记录每个节点的前驱。用于最后输出答案。整个转移过程(左括号的情况):

		node now = que.front(); que.pop();
        int x,y,z;
        x = now.x + (now.x < n && s1[now.x] == '(');
        y = now.y + (now.y < m && s2[now.y] == '(');
        z = now.z + 1;
        if(z <= N && dp[x][y][z] == inf){
            dp[x][y][z] = dp[now.x][now.y][now.z]+1;
            pre[x][y][z] = node(now.x,now.y,now.z,'(');
            que.push(node(x,y,z,0));
        }

AC代码:

#include <iostream>
#include <bits/stdc++.h>
#include <unordered_map>
//#define int long long
#define mk make_pair
#define gcd __gcd
using namespace std;
const double eps = 1e-10;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const int N = 2e2+7;
int n,m,k,t = 1,cas = 1;
int a[N],b[N];
struct node{
    int x,y,z;
    char val;
    node(){}
    node(int xx,int yy,int zz,char v){
        x = xx;
        y = yy;
        z = zz;
        val = v;
    }
}pre[N][N][N];
int dp[N][N][N];
queue<node> que;
string s1,s2;

void bfs(){
    memset(dp,inf,sizeof(dp));
    dp[0][0][0] = 0;
    que.push(node(0,0,0,0));
    while(!que.empty()){
        node now = que.front(); que.pop();
        int x,y,z;
        x = now.x + (now.x < n && s1[now.x] == '(');
        y = now.y + (now.y < m && s2[now.y] == '(');
        z = now.z + 1;
        if(z <= N && dp[x][y][z] == inf){
            dp[x][y][z] = dp[now.x][now.y][now.z]+1;
            pre[x][y][z] = node(now.x,now.y,now.z,'(');
            que.push(node(x,y,z,0));
        }

        x = now.x + (now.x < n && s1[now.x] == ')');
        y = now.y + (now.y < m && s2[now.y] == ')');
        z = now.z - 1;
        if(z >= 0 && dp[x][y][z] == inf){
            dp[x][y][z] = dp[now.x][now.y][now.z]+1;
            pre[x][y][z] = node(now.x,now.y,now.z,')');
            que.push(node(x,y,z,0));
        }
    }
}


signed main(){
    //cin>>t;
    while(t--){
        cin>>s1>>s2;
        n = s1.size();m = s2.size();
        bfs();
        char res[500];
        int pos = 0;
        node now = pre[n][m][0];
        res[pos++] = now.val;
        while(now.x+now.y+now.z){
            now = pre[now.x][now.y][now.z];
            res[pos++] = now.val;
        }
        res[pos] = 0;
        reverse(res,res+pos);
        cout<<res<<endl;
    }
    return 0;
}
/***
***/

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值