CF1172F Two Bracke t Sequences

题意:给两个字符串,求一个完整的$()$序列包含他们,且长度最短,$len\leq 200$

可以口胡数据范围就是三维$dp$,然后我们来确定下$dp$状态。

$dp[i][j][k]$,$i$表示已经含有$S$字符串前$i$位,$j$表示已经含有T字符串前$j$位,$k$是前缀后(一个完整的序列,$k=0$,他的前缀的$k>=0$,这样dp的时候有了边界条件)

  • $dp$的转移方程很好推。转移的话因为是记忆化的$dp$,所以只要记录他下一步会转移到哪里就好了。

</details>

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
const int N = 200 + 10;
const int inf = 1e9 + 7;
int dp[N][N][2 * N], tlen, slen;
char s[N], t[N];
char f[N][N][2 * N];
int dfs(int r1, int r2, int k)
{
//cout<<r1<<" "<<r2 <<" "<<k<<" "<<len<<endl;
if (k < 0 || k > 400)
return inf;
if (dp[r1][r2][k] != -1)
return dp[r1][r2][k];
if (r1 > slen && r2 > tlen)
return k;

int res = inf;
int dp1 = dfs(r1 + (r1 <= slen && s[r1] == '('), r2 + (r2 <= tlen && t[r2] == '('), k + 1) + 1;
int dp2 = dfs(r1 + (r1 <= slen && s[r1] == ')'), r2 + (r2 <= tlen && t[r2] == ')'), k - 1) + 1;
if (dp1 < dp2)
f[r1][r2][k] = '(';
else
f[r1][r2][k] = ')';
return dp[r1][r2][k] = min(dp1, dp2);
}
int main()
{
memset(dp, -1, sizeof(dp));
scanf("%s", s + 1);
scanf("%s", t + 1);
slen = strlen(s + 1);
tlen = strlen(t + 1);
dfs(1, 1, 0);
int r1 = 1, r2 = 1, k = 0;
while (r1 <= slen || r2 <= tlen)
{
printf("%c", f[r1][r2][k]);
if (f[r1][r2][k] == '(')
r1 += (r1 <= slen && s[r1] == '('), r2 += (r2 <= tlen && t[r2] == '('), k++;
else
r1 += (r1 <= slen && s[r1] == ')'), r2 += (r2 <= tlen && t[r2] == ')'), k--;
}
while (k > 0)
k--, printf(")");
}

</details>