Codeforces Round #501 (Div. 3) F. Bracket Substring
阿新 • • 發佈:2018-08-04
clu contest 轉移 oid ++ pre c++ end ret
題目鏈接
Codeforces Round #501 (Div. 3) F. Bracket Substring
題解
官方題解
http://codeforces.com/blog/entry/60949 ....看不懂
設dp[i][j][l]表示前i位,左括號-右括號=j,匹配到l了
狀態轉移,枚舉下一個要填的括號,用next數組求狀態的l,分別轉移
代碼
#include<bits/stdc++.h> using namespace std; const int maxn = 207; const int mod = 1e9 + 7; char s[maxn]; int next[maxn],dp[maxn][maxn][maxn],n; void GetNext(int l) { next[0] = 0; for(int i = 1; i <= l; i++) { int p = next[i-1]; while(p > 0 && s[p] != s[i]) p = next[p-1]; next[i] = p + 1; } } int main() { scanf("%d%s",&n,s + 1); int len = strlen(s + 1); GetNext(len); dp[0][0][0] = 1; for(int i = 0;i <= 2 * n;++ i) for(int j = 0;j <= n; ++ j) { for(int l = 0;l < len;++ l) { int x = l + 1; while(x > 0 && s[x] != '(') x = next[x - 1]; dp[i + 1][j + 1][x] = (dp[i + 1][j + 1][x] + dp[i][j][l]) % mod; x = l + 1; while(x > 0 && s[x] != ')') x = next[x - 1]; if(j > 0) dp[i + 1][j - 1][x] = (dp[i + 1][j - 1][x] + dp[i][j][l]) % mod; } dp[i + 1][j + 1][len] =(dp[i + 1][j + 1][len] + dp[i][j][len]) % mod; if(j > 0) dp[i + 1][j - 1][len] = (dp[i][j][len] + dp[i + 1][j - 1][len]) % mod; } cout << dp[2 * n][0][len] << endl; return 0; }
Codeforces Round #501 (Div. 3) F. Bracket Substring