JZOJ3377 【NOI2013模拟】抽奖(lottery) 期望的线性性

来源:互联网 发布:js new是什么意思 编辑:程序博客网 时间:2024/06/10 08:50

题目大意

N位同学参与抽奖,每位同学在抽奖箱中放入了Ai写有自己姓名的小球。抽奖总共有M轮,每轮随机地抽出一个小球并记录。之后,将这个小球放回抽奖箱。每位同学如果写有他的名字的球被抽出了X次,则他将获得奖金X2元。现在要求计算总奖金的期望值和获得奖金大于0的人数的期望值。

N,M105
Ai109

解题思路

先设pi表示一个抽到第i个人的概率。
我们把每次抽奖分开考虑,假设我们之前已经抽了t个球,现在我们设t+1个球抽到第i个人,这个人已经被抽到mi次。那么这一个球带来的贡献Δ=(mi+1)2m2i=2mi+1。那么我们考虑对两边求期望,根据期望的线性性

E[Δi]=E[2mi+1]=2E[mi]+1E[mi]=tpi

所以E[Δi]=2tpi+1。那么对于一个一次抽奖的期望就很好计算了:
E[Δ]=i=1N(piE[Δi])=i=1N(2tp2i+pi)=2ti=1Np2i+1

那么对于第一问的答案只需把t=1...N的情况加起来就可以了。
Ans1=t=0M1(2ti=1Np2i+1)=2(t=0M1t)(i=1Np2i)+M=M(M1)i=1Np2i+M

同样对于第二问也十分好求,由于期望的线性性,我们考虑对每个人分开考虑然后加起来,显然
Ans2=i=1N[1(1pi)M]=Ni=1N(1pi)M

程序

//YxuanwKeith#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int MAXN = 1e5 + 5;int N, M, Num[MAXN];double P[MAXN];double Power(double x, int y) {    double Ans = 1;    for (; y; y >>= 1, x = x * x)         if (y & 1) Ans = Ans * x;    return Ans;}int main() {    scanf("%d%d", &N, &M);    int All = 0;    for (int i = 1; i <= N; i ++) {        scanf("%d", &Num[i]);        All += Num[i];    }    for (int i = 1; i <= N; i ++) P[i] = 1.0 * Num[i] / All;    double Ans = 1.0 * M * (M - 1);    double Sum = 0;    for (int i = 1; i <= N; i ++) Sum += P[i] * P[i];    Ans = Ans * Sum + M;    printf("%.2lf\n", Ans);    Ans = N;    for (int i = 1; i <= N; i ++) Ans -= Power(1 - P[i], M);    printf("%.2lf\n", Ans);}
1 0
原创粉丝点击