【Codeforces 629 C Famil Door and Brackets 】+ dp

47 篇文章 3 订阅
43 篇文章 0 订阅

C. Famil Door and Brackets
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.
Examples
Input

4 1
(

Output

4

Input

4 4
(())

Output

1

Input

4 3
(((

Output

0

Note

In the first sample there are four different valid pairs:

p = "(", q = "))"
p = "()", q = ")"
p = "", q = "())"
p = "", q = ")()" 

In the second sample the only way to obtain a desired string is choose empty p and q.

In the third sample there is no way to get a valid sequence of brackets.

把‘)’姑且用 -1代替,‘(’用 1代替,dp[i][j] : 字符串长度为i时,价值为j~递推式可以列写为:dp[i]j[]=dp[i-1][j-1]+dp[i-1][j+1]~每次计算 左边需要最少的价值~再依次枚举满足的左边价值~即可

AC代码:

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
const LL INF = 0x3f3f3f3f;
char st[1000010];
LL dp[2010][2010];
void init(){ // dp[i][j] : 字符串长度为i时,价值为j
    dp[0][0] = 1;
    for(int i = 1 ; i <= 2002 ; 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;
    }
}
int main()
{
    int N,M;
    init();
    while(scanf("%d %d",&N,&M) != EOF){
        scanf("%s",st);
        LL sum = 0,cut = -INF;
        for(int i = 0 ; i < M; i++){
            if(st[i] == ')') sum++;
            else sum--;
            cut = max(cut,sum); // 更新前缀最少需要的左括号数
        }
        LL ans = 0;
        for(int i = 0 ; i <= N - M ; i++)
            for(int j = 0 ; j <= N - M; j++){
                int k = j - sum;
                if(j >= cut && k <= N - M)
                    ans = (ans + dp[i][j] * dp[N - M - i][k] % mod ) % mod;
            }
            printf("%lld\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值