zoukankan      html  css  js  c++  java
  • Hdu 4465 Candy (快速排列组合+概率)

    题目链接:

      Hdu 4465 Candy

    题目描述:

      有两个箱子,每个箱子有n颗糖果,抽中第一个箱子的概率为p,抽中另一个箱子的概率为1-p。每次选择一个箱子,有糖果就拿走一颗,没有就换另外一个箱子。问换箱子的时候,另外一个箱子中剩下糖果的期望值。

    解题思路:

      注意题目描述,其中任意一个箱子没有糖果,另一个箱子中剩下糖果个数的期望,而不是第一个箱子没有糖果。不是把其中一个箱子取空时,另一个箱子剩下糖果的期望,而是其中一个箱子取空再换另外一个箱子时,这个箱子的期望。

      可以根据期望性质画出公式:ans = (n-i) * C(n+i,n) * (p^(n+1)*(1-p)^i + (1-p)^(n+1)*p^i) (0<=i<=n);新的问题又来了,C(n+i,n)由于n的原因可能会向上溢出,而p^(n+1)又可能会很小,然后向下溢出。可以分别对他们进行取log,log(C(n+i,n))范围变小,log(p^(n+1))变成负数,方便保存。

     1 /*
     2 ******未处理精度的代码,推论严密美丽也无卵用********
     3 期望公式Ε=∑ P * N    p为概率 n为数量
     4  P=p*C(n,m)*p^n*(1-p)^(m-n)
     5  c(m,n)=c(m-1,n)*m/(m-n)
     6 概率
     7 m=0      p^(n+1)
     8 m=1      p^(n+1)q
     9 m=2      p^(n+1)q^2
    10 */
    11 #include <cstdio>
    12 #include <iostream>
    13 #include <algorithm>
    14 using namespace std;
    15 
    16 int main ()
    17 {
    18     int t, i, l = 1;
    19     double ans, p1, p2, res1, res2;
    20     while (scanf ("%d %lf", &t, &p1) != EOF)
    21     {
    22         p2 = (1.0 - p1);
    23         res1 = t * p1;
    24         ans = 1;
    25         res2 = t * p2;
    26         for (int i=1; i<=t; i++)
    27         {
    28             ans *= p1 * p2 * (t + i) / i;
    29             res1 += ans * (t - i);
    30             res1 *= p1;
    31             res2 += ans * (t - i);
    32             res2 *= p2;
    33         }
    34         printf ("Case %d: %6lf
    ", l++, res1+res2);
    35     }
    36     return 0;
    37 }
     1 /*
     2     取log处理精度问题,exp还原结果
     3 */
     4 #include <cmath>
     5 #include <cstdio>
     6 #include <iostream>
     7 #include <algorithm>
     8 using namespace std;
     9 const int maxn = 400005;
    10 double Logf[maxn];
    11 void init ()
    12 {
    13     Logf[0] = 0;
    14     for (int i=1; i<maxn; i++)
    15         Logf[i] = Logf[i-1] + log(i*1.0);
    16 }
    17 double C (int m, int n)
    18 {
    19     return Logf[m] - Logf[n] - Logf[m-n];
    20 }
    21 int main ()
    22 {
    23     int n, cas = 1;
    24     double p1, p2, ans;
    25     init ();
    26     while (scanf ("%d %lf", &n, &p1) != EOF)
    27     {
    28         ans = 0;
    29         p2 = 1.0 - p1;
    30         p1 = log(p1);
    31         p2 = log(p2);
    32         for (int i=0; i<n; i++)
    33         {
    34             ans += ((n-i) * exp(C(n+i, n) + (n+1)*p1 + i*p2));
    35             ans += ((n-i) * exp(C(n+i, n) + (n+1)*p2 + i*p1));
    36         }
    37         printf ("Case %d: %f
    ", cas++, ans);
    38     }
    39     return 0;
    40 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    对比git rm和rm的使用区别
    Gerrit日常维护记录
    [原创]Gerrit中文乱码问题解决方案分享
    MySQL 高可用架构
    MySQL 高可用架构
    Android L开发指南
    如何使用GOOGLE高级搜索技巧
    Linux定时关机
    Android源码批量下载及导入到Eclipse
    怎样将Android SDK源码 导入到Eclipse中?
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4767904.html
Copyright © 2011-2022 走看看