• [poj1322]Chocolate——生成函数


    题目大意:

    一共有(c)种糖果,取(n)次,每次取到糖果种类都是等概率的,求有(m)种糖果个数为奇数个的概率。

    思路:

    直接概率DP时间复杂度太高,卡常数也不太好卡。

    将每次取出来的糖果看成是一个带有重复元素的排列,直接计算复合条件的排列数量。

    考虑符合条件的最后的序列的考虑EGF(指数型生成函数),可得出现次数为偶数次的糖果的生成函数为:

    [F_0(x)=sum_{i=0}^{infty}frac{x^{2i}}{(2i)!}=frac{e^x+e^{-x}}{2} ]

    出现奇数次的糖果的生成函数为:

    [F_1(x)=sum_{i=0}^{infty}frac{x^{2i+1}}{(2i+1)!}=frac{e^x-e^{-x}}{2} ]

    可以得到最后的答案的生成函数为:

    [F_1^{m}(x) imes F_0^{c-m}(x)=(frac{e^x-e^{-x}}{2})^m imes(frac{e^x+e^{-x}}{2})^{c-m} ]

    (e^x)看成是一个整体,然后两边分别二项式展开之后做卷积,然后再将(e^x)展开即可得到第(n)项系数。

    [egin{aligned} G(x)&=2^{-c} imes sum_{i=0}^{m}(-1)^i{mchoose i} imes e^{(m-2i)x} imes sum_{j=0}^{c-m}{c-mchoose j} imes e^{(2j-c+m)x}\ &=2^{(-c)} imes sum_{i=0}^{m}sum_{j=0}^{c-m}(-1)^i{mchoose i}{c-mchoose j} imes e^{(2m-2i+2j-c)x}\ &=2^{(-c)} imes sum_{i=0}^{m}sum_{j=0}^{c-m}(-1)^i{mchoose i}{c-mchoose j} imes sum_{k=0}^{infty}frac{((2m-2i+2j-c)x)^k}{k!} end{aligned} ]

    设第(n)项的系数为(a_n),最后的答案为:

    [frac{a_n imes{cchoose m} imes n!}{2^c imes c^n} ]

    垃圾poj
    坑点:
    如果用实数类去计算,中间过程可能会爆精度,特别是中间的快速幂,建议将最后分母的那个(c^m)移到系数的快速幂里面,这样会让中间过程的数值小一些。
    好像用不了%lf,直接用%f即可。
    交C++好像过不了。

    /*=======================================
     * Author : ylsoi
     * Time : 2019.2.1
     * Problem : Chocolate
     * E-mail : ylsoi@foxmail.com
     * ====================================*/
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    
    #define REP(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)
    #define DREP(i,a,b) for(int i=a,i##_end_=b;i>=i##_end_;--i)
    #define debug(x) cout<<#x<<"="<<x<<" "
    #define fi first
    #define se second
    #define mk make_pair
    #define pb push_back
    typedef long long ll;
    
    using namespace std;
    
    void File(){
        freopen("poj1322.in","r",stdin);
        freopen("poj1322.out","w",stdout);
    }
    
    template<typename T>void read(T &_){
    	_=0; T fl=1; char ch=getchar();
    	for(;!isdigit(ch);ch=getchar())if(ch=='-')fl=-1;
    	for(;isdigit(ch);ch=getchar())_=(_<<1)+(_<<3)+(ch^'0');
    	_*=fl;
    }
    
    const int maxn=1e6+10;
    const int maxc=200+10;
    int c,n,m;
    double C[maxc][maxc],ans;
    
    double qpow(double x,int y){
    	double ret=1;
    	while(y){
    		if(y&1)ret=ret*x;
    		x=x*x;
    		y>>=1;
    	}
    	return ret;
    }
    
    void init(){
    	C[0][0]=1;
    	REP(i,1,200){
    		C[i][0]=1;
    		REP(j,1,i)C[i][j]=C[i-1][j-1]+C[i-1][j];
    	}
    }
    
    int main(){
        File();
    	init();
    	while(~scanf("%d%d%d",&c,&n,&m)){
    		if(!c)break;
    		ans=0;
    		if(m>c || m>n || (n-m)%2){
    			printf("0.000
    ");
    			continue;
    		}
    		REP(i,0,m)REP(j,0,c-m)
    			ans+=(i%2 ? -1 : 1)*C[m][i]*C[c-m][j]*qpow((2*m-2*i+2*j-c)*1.0/c,n);
    		ans=ans*C[c][m]/qpow(2,c);
    		printf("%.3f
    ",ans);
    	}
        return 0;
    }
    
    
  • 相关阅读:
    22_selenium_使用cookie直接登录
    21_无头模式
    自动化测试-设计模式-介绍
    Doorls
    pytest-Allure报告
    pytest-架构1
    pytest-第一次学习梳理
    web测试
    测试-工时评估
    封装pyuic5转换ui文件的脚本
  • 原文地址:https://www.cnblogs.com/ylsoi/p/10347213.html
Copyright © 2020-2023  润新知