zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    各种有趣vbs,bat脚本
    weblogic ssrf 漏洞笔记
    jboss反序列化漏洞实战渗透笔记
    脏牛提权
    Bugku-cms1
    通过Tomcat Manager拿shell
    【转】网站渗透入侵常见谷歌黑客语法总结
    【转】AWVS扫描小技巧
    学习笔记
    三栏布局那些事儿
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/9515177.html
Copyright © 2011-2022 走看看