• 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;
    }
  • 相关阅读:
    html/form表单常用属性认识
    css复杂动画(animation属性)
    css样式水平居中和垂直居中的方法
    css简单动画(transition属性)
    html/css中map和area的应用
    html/css弹性布局的几大常用属性详解
    webpack优化配置
    webpack配置详解
    使用Node.js搭建一个简单的web服务器(二):搭建一个简单的服务器
    使用Node.js搭建一个简单的web服务器(一):Node.js入门
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5205793.html
Copyright © 2020-2023  润新知