1. 程式人生 > >Codeforces 1015F Bracket Substring AC自動機 + dp

Codeforces 1015F Bracket Substring AC自動機 + dp

name esp ems bsp str rac pro style sizeof

Bracket Substring

這麽垃圾的題怎麽以前都不會寫啊, 現在一眼怎麽就會啊。。。。

考慮dp[ i ][ j ][ k ][ op ] 表示 已經填了 i 個空格, 末尾串匹配到 所給串的 第 j 個, 已經放了 k 個左括號, 是否存在所給串的方案數。

因為不匹配的不是從頭開始的, 所以暴力求下一個或者直接ac自動機都可以。

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define
se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = 200 + 7
; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T& a, S b) {a -= b; if
(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;} struct Ac { int ch[N][26], f[N], tot, sz; int n, tar, dp[N][N][N][2]; char s[N]; inline int newNode() { tot++; f[tot] = 0; memset(ch[tot], 0, sizeof(ch[tot])); return tot; } void init(int _sz) {sz = _sz; tot = -1; newNode();} inline int idx(int c) {return c - (;} void addStr(char* s) { int u = 0; for(int i = 0; s[i]; i++) { int c = idx(s[i]); if(!ch[u][c]) ch[u][c] = newNode(); u = ch[u][c]; } tar = u; } void build() { queue<int> que; for(int c = 0; c < sz; c++) { int v = ch[0][c]; if(!v) ch[0][c] = 0; else f[v] = 0, que.push(v); } while(!que.empty()) { int u = que.front(); que.pop(); for(int c = 0; c < sz; c++) { int v = ch[u][c]; if(!v) ch[u][c] = ch[f[u]][c]; else f[v] = ch[f[u]][c], que.push(v); } } } void solve() { init(2); scanf("%d", &n); scanf("%s", s); addStr(s); build(); dp[0][0][0][0] = 1; for(int i = 0; i < 2 * n; i++) { for(int u = 0; u <= tot; u++) { for(int c = 0; c <= n; c++) { for(int p = 0; p < 2; p++) { if(!dp[i][u][c]) continue; if(c <= n) { int v = ch[u][0]; add(dp[i + 1][v][c + 1][p || v == tar], dp[i][u][c][p]); } if(i - c < c) { int v = ch[u][1]; add(dp[i + 1][v][c][p || v == tar], dp[i][u][c][p]); } } } } } int ans = 0; for(int u = 0; u <= tot; u++) add(ans, dp[2 * n][u][n][1]); printf("%d\n", ans); } } ac; int main() { ac.solve(); return 0; } /* */

Codeforces 1015F Bracket Substring AC自動機 + dp