hdu 5184
题目大意:一个n,然后一串括号,括号数量 大于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暂时看不懂。

京公网安备 11010502036488号