• HDU 1521


    指数型生成函数。做这题时,回去看看组合数学才知道,指数生成函数求的就是多重集合的r排列数。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #define N 15
    
    using namespace std;
    
    struct PQ{
    	int p,q;
    };
    
    PQ c1[N],c2[N];
    int num[N];
    PQ cal;
    int Q[N];
    
    int gcd(int a,int b){
    	if(b==0) return a;
    	return gcd(b,a%b);
    }
    
    PQ addsum(PQ a,PQ b){
    	PQ tmp;
    	tmp.q=a.q*b.q;
    	tmp.p=a.p*b.q+a.q*b.p;
    	int g=gcd(max(tmp.p,tmp.q),min(tmp.p,tmp.q));
    	tmp.p/=g; tmp.q/=g;
    	return tmp;
    }
    
    int main(){
    	int n,m,ptmp,qtmp;
    	Q[0]=1;
    	for(int i=1;i<N;i++)
    	Q[i]=Q[i-1]*i;
    	while(scanf("%d%d",&n,&m)!=EOF){
    		for(int i=1;i<=n;i++)
    		scanf("%d",&num[i]);
    		for(int i=0;i<N;i++){
    			c1[i].p=c2[i].p=0;
    			c1[i].q=c2[i].q=1;
    		}
    		for(int i=0;i<=num[1];i++)
    		c1[i].p=1,c1[i].q=Q[i];
    		for(int i=2;i<=n;i++){
    			for(int j=0;j<N;j++){
    				for(int k=0;k+j<N&&k<=num[i];k++){
    					ptmp=1,qtmp=Q[k];
    					cal.p=ptmp*c1[j].p;cal.q=qtmp*c1[j].q;
    					ptmp=gcd(max(cal.p,cal.q),min(cal.p,cal.q));
    					cal.p/=ptmp; cal.q/=ptmp;
    					c2[k+j]=addsum(cal,c2[k+j]);
    				}
    			}
    			for(int j=0;j<N;j++)
    			c1[j]=c2[j],c2[j].p=0,c2[j].q=1;
    		}
    		printf("%d
    ",c1[m].p*Q[m]/c1[m].q);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    <Yii 学习>写入日志
    微信支付:curl出错,错误码:60
    PHPstorm创建注释模版
    Yii 常用命令
    Linux启动/停止/重启Mysql数据库的方法
    php foreach跳出本次/当前循环与终止循环方法
    介绍Sublime3下两款Markdown插件
    规范
    业务流程时序图
    数据字典
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4007062.html
Copyright © 2020-2023  润新知