C. Famil Door and Brackets
题目连接:
http://www.codeforces.com/contest/629/problem/C
Description
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.
Input
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.
Output
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.
Sample Input
4 1
(
Sample Output
4
Hint
题意
给你一个长度m的括号序列,然后让你补全成长度为n的合法括号序列
问你一共有多少种补全的方案
题解:
dp
dp[i][j]表示长度为i,当前平衡度为j的方案数是多少
然后暴力枚举ij就好了,左右乘法原则处理一下贡献
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2005;
const int mod = 1e9+7;
long long dp[maxn][maxn];//长度为i,平衡度为j的方案数
int n,m;
char s[100005];
int main()
{
dp[0][0]=1;
for(int i=1;i<=2000;i++)
{
dp[i][0]=dp[i-1][1];
for(int j=1;j<=i;j++)
dp[i][j]=(dp[i-1][j-1]+dp[i-1][j+1])%mod;
}
scanf("%d%d",&n,&m);
scanf("%s",s+1);
int sum=0,l=0,r=0;
for(int i=1;i<=m;i++)
{
if(s[i]=='(')sum++;
else sum--;
l=min(sum,l);
}
l=-l;
sum=0;
for(int i=m;i;i--)
{
if(s[i]==')')sum++;
else sum--;
r=min(sum,r);
}
r=-r;
long long ans = 0;
for(int i=0;i<=n-m;i++)
{
for(int j=0;j<=n-m;j++)
{
int len2 = n-m-i;
int j2 = j-sum;
if(j2<=n-m&&i>=l&&j2>=r)
ans=(ans+dp[i][j]*dp[len2][j2])%mod;
}
}
cout<<ans<<endl;
}