Codeforces Round #343 (Div. 2) C. Famil Door and Brackets

题目链接:

http://codeforces.com/contest/629/problem/C

题意:

长度为n的括号,已经知道的部分的长度为m,现在其前面和后面补充‘(',或')',使得其长度为n,且每个左括号都能找到右括号与它匹配。

题解:

dp[i][j]表示长度为i,平衡度为j的合法括号序列的总数,这里平衡度定义是‘('比')'多多少个,或')'比’('多多少个。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 2222;
 8 const int maxm = 1e5 + 10;
 9 const int mod = 1e9 + 7;
10 const int INF = 0x3f3f3f3f;
11 typedef __int64 LL;
12 
13 LL dp[maxn][maxn];
14 void pre() {
15     memset(dp, 0, sizeof(dp));
16     dp[0][0] = 1;
17     for (int i = 1; i < maxn; i++) {
18         dp[i][0] = dp[i - 1][1];
19         for (int j = 1; j <= i; j++) {
20             dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j + 1]) % mod;
21         }
22     }
23 }
24 
25 int n, m;
26 char str[maxm];
27 
28 int main() {
29     pre();
30     scanf("%d%d", &n, &m);
31     scanf("%s", str);
32     int l = 0, r = 0, mi = INF;
33     for (int i = 0; i < m; i++) {
34         if (str[i] == '(') l++;
35         else r++;
36         mi = min(mi, l - r);
37     }
38     LL ans = 0;
39     for (int i = 0; i <= n - m; i++) {
40         for (int j = max(0, -mi); j <= i; j++) {
41             int t = j + l - r;
42             if (t > n - m - i) continue;
43             ans = (ans + dp[i][j] * dp[n - m - i][t] % mod) % mod;
44         }
45     }
46     printf("%I64d\n", ans);
47     return 0;
48 }

 

posted @ 2016-06-06 13:43  fenicnn  阅读(184)  评论(0编辑  收藏  举报