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

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;
}
    原文作者:qscqesze
    原文地址: https://www.cnblogs.com/qscqesze/p/5205793.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞