As Famil Door’s birthday is coming, some of his friends (like Gabi) decided to buy a present for him. His friends are going to buy a string consisted of round brackets since Famil Door loves string of brackets of length n more than any other strings!
The sequence of round brackets is called valid if and only if:
- the total number of opening brackets is equal to the total number of closing brackets;
- for any prefix of the sequence, the number of opening brackets is greater or equal than the number of closing brackets.
Gabi bought a string s of length m (m ≤ n) and want to complete it to obtain a valid sequence of brackets of length n. He is going to pick some strings p and q consisting of round brackets and merge them in a string p + s + q, that is add the string p at the beginning of the string s and string q at the end of the string s.
Now he wonders, how many pairs of strings p and q exists, such that the string p + s + q is a valid sequence of round brackets. As this number may be pretty large, he wants to calculate it modulo 109 + 7.
First line contains n and m (1 ≤ m ≤ n ≤ 100 000, n - m ≤ 2000) — the desired length of the string and the length of the string bought by Gabi, respectively.
The second line contains string s of length m consisting of characters '(' and ')' only.
Print the number of pairs of string p and q such that p + s + q is a valid sequence of round brackets modulo 109 + 7.
4 1 (
4
4 4 (())
1
4 3 (((
0
solution:
先统计字符串s中‘(’的最小前缀和为minn,s中前缀和为x,那么p只需要满足p的前缀和+minn>=0,符合这样的不等式的p都是可行解,那么我们预处理出一个dp[i][j],代表i个括号平衡度为j的个数,那么之后枚举p的长度i和p的平衡度j,在满足 p的前缀和(j)+minn>=0 和 q的前缀和(j+x)<=m-n-i(及q的长度) 其实在这里q的前缀和应该为-(j+x),因为总体前缀和应为0 但因为对称 所以可看成j+x
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 200;
const int mod = 1e9 + 7;
char s[maxn];
long long dp[2500][2500];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
scanf("%s", s + 1);
dp[0][0] = 1;
for (int i = 1; i <= n - m; i++)//预处理长度为n-m,平衡度为0~i的dp[i][j]
for (int j = 0; j <= i; j++)
if (j > 0)dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j + 1])%mod;
else dp[i][j] = dp[i - 1][j+1];
int minn = m+1,x=0;
for (int i = 1; i <= m; i++)
{
if (s[i] == '(')x++;
else x--;
minn = min(minn, x);
}
long long ans = 0;
for (int i = 0; i <= n - m; i++)
for (int j = 0; j <= i; j++)
if (j + minn >= 0 && j + x <= n - m - i)
ans = (ans + dp[i][j] * dp[n - m - i][j + x]) % mod;
printf("%I64d\n", ans);
}