zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    	}
    	return 0;
    }
    

      

     

  • 相关阅读:
    Java集合框架--List去重
    solr管理集合
    关于unix环境高级编程、Linux程序设计两部书浅谈
    ubuntu17.10安装lnmp安装包的核心问题-gcc版本、g++版本
    手机谷歌浏览器简洁处理方法
    Ubuntu当状态栏网络图标隐藏的解决方法汇总
    Ubuntu创建WiFi:16.0.4
    关于virtual box 虚拟机使用
    关于json转义中文
    xp 允许序列号
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4322212.html
Copyright © 2011-2022 走看看