Codeforces 1015F Bracket Substring
Posted xunzhen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1015F Bracket Substring相关的知识,希望对你有一定的参考价值。
Description
给定一个正整数\(n\),问有多少个长度为\(2n\)的合法括号序列包含一个给定的子括号序列\(s\)(不一定合法)
\(n \leq 100, |s| \leq 200\)
Solution
我们可以先预处理出\(to[i][0/1]\),表示如果后缀已经\(s\)匹配上了前\(i\)个字符,再填一个左/右括号后,后缀和\(s\)前缀匹配的长度。这个东西可以直接暴力预处理,也可以用\(kmp\)来处理
然后就是设\(dp[i][j][k][0/1]\),表示考虑到第\(i\)个位置,左括号比右括号多\(i\)个,当前后缀和\(s\)已经匹配上了\(k\)位,当前串是否已经包含了\(s\)串。转移就直接枚举当前位置填什么,并利用预处理出来的\(to\)数组转移
Code
#include <bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
#define mp make_pair
#define squ(x) ((LL)(x) * (x))
#define debug(...) fprintf(stderr, __VA_ARGS__)
typedef long long LL;
typedef pair<int, int> pii;
template<typename T> inline bool chkmax(T &a, const T &b) return a < b ? a = b, 1 : 0;
template<typename T> inline bool chkmin(T &a, const T &b) return a > b ? a = b, 1 : 0;
inline int read()
int sum = 0, fg = 1; char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') fg = -1;
for (; isdigit(c); c = getchar()) sum = (sum << 3) + (sum << 1) + (c ^ 0x30);
return fg * sum;
const int maxn = 200 + 10;
const int mod = 1e9 + 7;
inline void Add(int &x, int y) x += y, x -= (x >= mod ? mod : 0);
int n, m, dp[maxn][maxn][maxn][2], to[maxn][2];
char s[maxn];
int fail[maxn];
inline void get_next()
for (int i = 2, j = 0; i <= m; i++)
while (j && s[j + 1] != s[i]) j = fail[j];
if (s[j + 1] == s[i]) ++j;
fail[i] = j;
int main()
#ifdef xunzhen
freopen("bracket.in", "r", stdin);
freopen("bracket.out", "w", stdout);
#endif
n = read() << 1, scanf("%s", s + 1), m = strlen(s + 1);
get_next();
for (int i = 0; i < m; i++)
int j = i;
while (j && s[j + 1] != '(') j = fail[j];
if (s[j + 1] == '(') to[i][0] = j + 1;
j = i;
while (j && s[j + 1] != ')') j = fail[j];
if (s[j + 1] == ')') to[i][1] = j + 1;
dp[0][0][0][0] = 1;
for (int i = 0; i < n; i++)
for (int j = 0; j <= i; j++)
for (int k = 0; k < m; k++)
if (j) Add(dp[i + 1][j - 1][to[k][1]][to[k][1] == m], dp[i][j][k][0]);
Add(dp[i + 1][j + 1][to[k][0]][to[k][0] == m], dp[i][j][k][0]);
if (j) Add(dp[i + 1][j - 1][m][1], dp[i][j][m][1]);
Add(dp[i + 1][j + 1][m][1], dp[i][j][m][1]);
cout << dp[n][0][m][1] << endl;
return 0;
以上是关于Codeforces 1015F Bracket Substring的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces 990C Bracket Sequences Concatenation Problem
CodeForces - 5C Longest Regular Bracket Sequence
[codeforces]#350E. Correct Bracket Sequence Editor
Codeforces 1132A. Regular Bracket Sequence