• 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);
        }
    }
  • 相关阅读:
    (转载)Android mac 真机调试
    Google Map SDK for iOS
    autolayout under navigation bar
    Xamarin Mono For Android、Monotouch 安装
    不错的ORM调试查看SQL插件
    在Windows 8.1系统上配置免安装版mysql-5.6.21-winx64
    VS2013 EF6连接MySql
    安卓离线SDK Windows版 资源包下载地址全集
    WndProc函数参数列表
    反射创建对象
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6940487.html
Copyright © 2020-2023  润新知