HDU4465 Candy

Posted Blogggggg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU4465 Candy相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4465

知识点:  概率和期望

题目大意:

  懒小孩有 2 个盒子,每个盒子里面有 \(n (1 \le n \le 2 \times 10^5)\) 颗糖,懒小孩每天有 \(p (0 \le p \le 1)\) 的概率打开第一个盒子,当然,打开另一个盒子的概率就是 \(p-1\) 了。问当某一天他打开一个盒子,发现其中没有糖,然后再去打开另一个盒子的时候,该盒子中的糖的期望值是多少?

解题思路:

  设小孩在第 \(i  (i: n+1 \to 2n+1)\) 天发现一个盒子里面没有糖,此时有两种情况:第一个盒子没有糖,则第二个盒子里面糖数的期望值为 \(C_{i-1}^{n} \underline{p^{n+1}} (1-p)^{i-1-n} (2n-i+1)\) (注意划线处是 \(p^{n+1}\) 而不是 \(p^n\) ,因为第一个盒子一共被选了 \(n+1\) 次);同理,第二个盒子没有糖时,第一个盒子里面糖数的期望值为 \(C_{i-1}^{n} p^{i-1-n} (1-p)^{n+1} (2n-i+1)\) .

  公式明确了,而且我们不难发现:第 \(i+1\) 天的期望值可以由第 \(i\) 天推得,但现在的问题是:当 n 很大时,组合数会大得爆 \(long long\),但概率在 N 多次方下会小成 0 。于是我们只好用 \(log()\)先取这两者的对数,然后先在对数的状态下将二者加起来,然后再用 \(exp()\) 处理他们的和,这样得到的结果也相当于两者相乘的积。

AC代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     int n,kase=1;
10     double p;
11     while(scanf("%d%lf",&n,&p)==2){
12         double C=log(1.0);
13         double p1=0,p2=0;   //p1 用于求第一种情况,而 p2 用于求第二种情况
14         for(int i=0;i<n+1;i++)    p1+=log(p),p2+=log(1-p);
15         double ans=0;
16         for(int i=n+1;i<=2*n+1;i++){
17             ans=ans+(exp(C+p1)+exp(C+p2))*(2*(double)n-i+1);
18             C+=log((double)i/((double)i-n));
19             p1+=log(1-p),p2+=log(p);
20         }
21         printf("Case %d: %.6lf\n",kase++,ans);
22     }
23     return 0;
24 }

 

以上是关于HDU4465 Candy的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5654 xiaoxin and his watermelon candy 离线树状数组

hdu 5380 Travel with candy(双端队列)

HDU 4780 Candy Factory

dp hdu5653 xiaoxin and his watermelon candy

hdu 5654 xiaoxin and his watermelon candy 树状数组维护区间唯一元组

线段树+离线 hdu5654 xiaoxin and his watermelon candy