zoukankan      html  css  js  c++  java
  • uva 1639 Candy (对数处理精度)

    https://vjudge.net/problem/UVA-1639

    有两个盒子各有n(n≤2*10 5 )个糖,每天随机选一个(概率分别为p,1-p),然后吃一颗糖。

    直到有一天,打开盒子一看,没糖了!

    输入n, p,求此时另一个盒子里糖的个数的数学期望。

    若最后打开第1个盒子,此时第2个盒子有i颗,则这之前打开过n+(n-i)次盒子,

    其中有n次取的是盒子1,其余n-i次取的盒子2,

    概率为C(2n-i, n)*p^(n+1) *(1-p)^(n-i)

    注意p的指数是n+1,因为除了前面打开过n次盒子1之外,最后又打开了一次。

    同理,若最后打开第2个盒子,此时第1个盒子有i颗,

    概率为 C(2n-i, n)*(1-p)^(n+1) * p^(n-i)

    所以ans=

    Σ i*C(2n-i, n)*p^(n+1) *(1-p)^(n-i)

    +

    Σ i*C(2n-i, n)*(1-p)^(n+1) * p^(n-i)

    精度处理:转化为对数v

    设v1(i) = ln(C(2n-i, n)) + (n+1)ln(p) +(n-i)ln(1-p),

    v2(i) = ln(C(2n-i, n)) + (n+1)ln(1-p) +(n-i)ln(p)

    最终答案为 Σ{ i*(e^v1(i) +e^v2(i) ) }

     

    #include<cmath>
    #include<cstdio>
    #define N 200001
    using namespace std;
    long double logsum[N*2];
    int main()
    {
        for(int i=1;i<N*2;i++) logsum[i]=logsum[i-1]+log((long double)i);
        int n,t=0; 
        double p,ans;
        while(scanf("%d",&n)!=EOF)
        {
            scanf("%lf",&p);
            ans=0.0; 
            long double tmp1=(n+1)*log(p),tmp2=(n+1)*log(1-p);
            long double logp=log(p),logpp=log(1-p);
            for(int i=1;i<=n;i++)
            {
                long double k=logsum[2*n-i]-logsum[n]-logsum[2*n-i-n];
                ans+=(i*(exp(k+tmp1+(n-i)*logpp)+exp(k+tmp2+(n-i)*logp)));
            }
            t++;
            printf("Case %d: %.6f
    ",t,ans);
        }
    }
  • 相关阅读:
    Linux安装nginx
    Linux安装vsftp服务
    maven的Tomcat插件使用
    Mybatis逆向工程生成代码
    千里之行,始于足下
    java 通过反射获取注解
    天气预报需要用到的jar包
    JDBC 利用反射 配置文件
    从网页下载图片的代码
    装箱/拆箱 对象排序
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6940487.html
Copyright © 2011-2022 走看看