HDU 5184

卡特兰数的一个变形而已。

一个经典的习题变过来的:

n+m个人排队买票,并且满足,票价为50元,其中n个人各手持一张50元钞票,m个人各手持一张100元钞票,除此之外大家身上没有任何其他的钱币,并且初始时候售票窗口没有钱,问有多少种排队的情况数能够让大家都买到票。

此时答案是:

反过来考虑就是,把右括号看成n,左括号看成m,就自然符合上述了。

#include <cstdio> 
#include <iostream> 
#include <cstring>  
#include <cctype>  
#include <algorithm>  
#define LL __int64
using namespace std; 

const LL N=1000005;
const LL MOD=1000000007;

LL mod[N];
LL ny[N];
char str[N];
int n;

LL C(int a,int b){
	if(b<0 || a<0 || a<b) return 0;
	return mod[a]*ny[b]%MOD*ny[a-b]%MOD;
}


int for_ny(int a,int m){
	int p=1,q=0,b=m,c,d;
	while(b>0){
		c=a/b;
		d=a; a=b; b=d%b;
		d=p; p=q; q=d-c*q;
	}
	return p<0?p+m:p;
}

int main(){
	mod[0]=1;
	ny[0]=for_ny(mod[0],MOD);
	for(int i=1;i<N;i++){
		mod[i]=(mod[i-1]*i)%MOD;
		ny[i]=(LL)for_ny((int)mod[i],(int)MOD);
	}
	while(scanf("%d",&n)!=EOF){
		getchar();
		scanf("%s",str);
		if(n%2){
			puts("0");
			continue;
		}
		int len=strlen(str);
		int p=0,q=0,i;
		for(i=0;i<len;i++){
			if(str[i]=='(') p++;
			if(str[i]==')') q++;
			if(q>p) break;
		}
		if(i<len){
			puts("0");
			continue;
		}
		n/=2;
		q=n-q,p=n-p;
		if(q<0||p<0){
			puts("0");
			continue;
		}
		int m=p+q;
		LL ans=(C(m,q)-C(m,q+1)+MOD)%MOD;
		printf("%I64d\n",ans);
	}
	return 0;
}

  

 

posted @ 2015-03-08 20:20  chenjunjie1994  阅读(400)  评论(0编辑  收藏  举报