hdu 5184


题目大意:一个n,然后一串括号,括号数量len 大于0小于等于n,问你在给出了前图片说明 个括号的情况下,长度为n的规则括号序列有多少种。
卡特兰数一眼题-----钟涛大佬。
题目的输入不一定保证是规则括号序列,所以如果n是奇数或者存在右括号的数量多于左括号的数量,或者左括号的数量大于n的一半是一定不能构成规则括号的。
统计左括号数量为 x ,右括号的数量为 y。总的方案数相当于从(1,1)到的路径数,经过对角线的方案数相当于从(1,1)到图片说明 的路径数。左括号看成是 1 ,意思是向右走1步,左括号看成是 0 ,意思是向上走1步,总的方案数就是图片说明 .组合数用逆元来求。涉及到减法,结果需要加上模数再取模,避免出现负数。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7,maxn=1e6;
ll f[maxn];
ll qpow(ll a,ll b) {
    ll res=1;
    while(b) {
        if(b&1)    res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
int main() {
    ll n;
    char s[maxn+1];
    f[0]=1;
    for(int i=1;i<=maxn;++i)    f[i]=f[i-1]*i%mod;
    while(~scanf("%d%s",&n,s)){
        ll x=0,y=0,ans=0,flag=0;
        for(int i=0;s[i];++i) {
            if(s[i]=='(')    ++x;
            else ++y;
            if(y>x) {
                flag=1;
                break;
            }
        }
        if(n&1||flag||x>n/2){
            puts("0");
            continue;
        }
        n/=2;
        ans=f[(n<<1)-x-y]*qpow(f[n-x]*f[n-y]%mod,mod-2)%mod-f[(n<<1)-x-y]*qpow(f[n-x-1]*f[n-y+1]%mod,mod-2)%mod;
        printf("%lld\n",(ans+mod)%mod);               
    }
}

hdu 5177暂时看不懂。