題意
給出
n,m(n≥m)
和一個長
m
的字符串 '('
和 ')'
兩種字符組成。
現在讓你在
s
首尾分別加字符串 '('
和 ')'
兩種字符,並且都可以是空串)。使得總串長度是
n
。並且滿足:1)總串的 '('
和 ')'
兩種字符數目相同。2)總串的任意一個前綴都滿足 '('
的數目大於等於 ')'
的數目。
請問加字符串的方案數是多少?答案取模
1≤n,m≤100000,n−m≤2000
鏈接:http://codeforces.com/contest/629/problem/C
解答
如果
m=0
,我們先考慮如何求。設
fi,j
表示前面
i
個字符有
考查中間的串,其實分別對
int ritMore = 0;
int maxRitMore = 0;
for (int i = 0; i < m; ++i) {
if (str.charAt(i) == ')')
ritMore++;
else ritMore--;
maxRitMore = Math.max(maxRitMore, ritMore);
}
这个 maxRitMore
的值就是
p
左边比右边至少要多的数目。但是这样就可以了么?当然还不行,我们还没考察
最终我们可以先枚舉
long res = 0;
for (int p = 0; p <= k; p++) {
int q = k - p;
for (int plft = (maxRitMore + p - 1) / 2; plft <= p; ++plft) {
int qlft = (n / 2) - plft - lftcnt;
int qrit = q - qlft;
if (qrit - qlft < maxLftMore || qlft < 0 || qrit < 0)
continue;
res = (res + c[p][plft] * c[q][qrit]) % MOD;
}
}
其中的 k
等于
n−m
;plft
表示
p
<script id="MathJax-Element-111" type="math/tex">p</script> 的做括号数。同理有剩下的命名。
这里是整个代码。