• Uva1639(概率期望/对数处理避免丢失精度)


    Uva1639

    题意:

    有两个盒子各有n个糖果(n<=200000),每天随机选择一个:选第一个盒子的概率是p(0 ≤ p ≤ 1),第二个盒子的概率为1-p,然后吃掉其中的一颗。直到有一天,随机选择一个盒子打开一看,没糖了!现在请你计算另一个盒子里剩下的糖果数量的期望值。

    解法:

    我们假设到第n天的时候取得是第1个盒子的糖,此时第2个盒子有i颗糖,则在此之前打开了n+(n-i)次盒子, 其中n次打开了第一个盒子,(n-i)次打开了第二个盒子,则概率是C(2n-i,n)*p^(n+1)*(1-p)^n-i。

    由于n高达20w,所以二次项系数会非常大,而后面的概率会非常小,所以如果直接计算会爆精度,所以这里我们用求对数的方法进行计算

     1 #include<iostream>
     2 #include<cmath>
     3 using namespace std;
     4 typedef long double lb;
     5 const int maxn = 2e5 + 5;
     6 long double logF[2 * maxn + 66];
     7 
     8 void generate() {
     9     //预处理出n!的log值
    10     logF[0] = 0;
    11     for (int i = 1; i <= maxn; i++)
    12         logF[i] = logF[i - 1] + log(i);
    13 }
    14 // C(n,m) = n!/(m!(n-m)!)
    15 long double logC(int n, int m) {
    16     return logF[n] - logF[m] - logF[n - m];
    17 }
    18 
    19 int main() {
    20     int n; double p;
    21     generate();
    22     int kase = 1;
    23     while (scanf("%d%lf", &n, &p)!=EOF) {
    24         double ans = 0;
    25         for (int i = 0; i <= n; i++) {
    26             long double v1 = logC(2 * n - i, n) + (n + 1)*log(p) + (n - i)*log(1 - p);
    27             long double v2 = logC(2 * n - i, n) + (n + 1)*log(1 - p) + (n - i)*log(p);
    28             ans += (i*(exp(v1) + exp(v2)));
    29         }
    30         printf("Case %d: %.6lf
    ", kase++, ans);
    31     }
    32     return 0;
    33 }
  • 相关阅读:
    docker架构的详解
    docker的核心原理-cgroup
    网络运维面试题
    100道linux运维笔试题
    运维岗位面试题集合
    python——筛子游戏
    同道前辈
    delphi中使用SocketStream读写数据的技巧
    百度地图API
    HTML中小meta的大作用
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/9515177.html
Copyright © 2020-2023  润新知