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;
}
/***
***/