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\n", 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\n", cas++, ans);
38     }
39     return 0;
40 }

 

posted @ 2015-08-28 21:15  罗茜  阅读(202)  评论(0编辑  收藏  举报