Candy UVA 1639 (数学期望)
有两个盒子各有n颗糖(n<=2*105),从两个盒子取糖的概率为p和1-p,直到一个盒子没糖,求另一个盒子中糖的个数的数学期望。
期望公式为:
E=∑i=1ni∗E(i)=∑j=0n(n−j)∗Cn+jj[pn+1∗(1−p)j+(1−p)n+1∗pj]E=\sum_{i=1}^{n}i*E(i)=\sum_{j=0}^{n}(n-j)*C_{n+j}^{j}[p^{n+1}*(1-p)^{j}+(1-p)^{n+1}*p^{j}]E=i=1∑ni∗E(i)=j=0∑n(n−j)∗Cn+jj[pn+1∗(1−p)j+(1−p)n+1∗pj]
假设最终看到盒子1没糖,那么盒子1刚好被选中n+1次(包括最后一次被选到)。那么从盒子2拿出糖的个数设为j,所以此时另一个盒子的糖的个数为n-j。整个过程中作出选择的次数为n+j+1,由于最后一次选择必为盒子1,所以只能在前n+j次选择盒子2,选择了j次(拿走了j颗糖),所以有C(n+j,j)种情况。
同理于对于最终看到盒子2没糖的情况。
由于n最高可达2*105,组合数最高可达C(2n,n),而且p的n次幂会非常趋近于0,如果直接相乘会造成较大的精度损失。这种情况可以用对数处理。
Cn+jj∗pn+1∗(1−p)j=eln(Cn+jj∗pn+1∗(1−p)j)=elnCn+jj+(n+1)∗lnp+j∗ln(1−p)C_{n+j}^j*p^{n+1}*(1-p)^j =e^{\ln_{}{(C_{n+j}^j*p^{n+1}*(1-p)^j)}} =e^{\ln_{}{C_{n+j}^j}+(n+1)*\ln_{}{p}+j*\ln_{}{(1-p)}}Cn+jj∗pn+1∗(1−p)j=eln(Cn+jj∗pn+1∗(1−p)j)=elnCn+jj+(n+1)∗lnp+j∗ln(1−p)
且Cn+j+1j+1=Cn+jj∗(n+j+1)j+1C_{n+j+1}^{j+1}=C_{n+j}^{j}*\frac{(n+j+1)}{j+1}Cn+j+1j+1=Cn+jj∗j+1(n+j+1)
lnCn+j+1j+1=lnCn+jj+ln(n+j+1)−ln(j+1)\ln_{}{C_{n+j+1}^{j+1}}=\ln{}{C_{n+j}^{j}}+\ln{(n+j+1)}-\ln{(j+1)}lnCn+j+1j+1=lnCn+jj+ln(n+j+1)−ln(j+1)
可以先计算指数部分。
E(n−j)=(n−j)∗[elnCn+jj+(n+1)∗lnp+j∗ln(1−p)+elnCn+jj+(n+1)∗ln(1−p)+j∗lnp]E(n-j)=(n-j)*[e^{\ln_{}{C_{n+j}^j}+(n+1)*\ln_{}{p}+j*\ln_{}{(1-p)}}+e^{\ln_{}{C_{n+j}^j}+(n+1)*\ln_{}{(1-p)}+j*\ln_{}{p}}]
E(n−j)=(n−j)∗[elnCn+jj+(n+1)∗lnp+j∗ln(1−p)+elnCn+jj+(n+1)∗ln(1−p)+j∗lnp]
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(void)
{
// freopen("out.txt","w",stdout);
int n;
long double p;
int t=1;
while(cin>>n>>p)
{
long double lgp=log(p);
long double lgp1=log(1-p);
long double lgpn=(n+1)*lgp;
long double lgp1n=(n+1)*lgp1;
long double lgc=log(1);
long double ans1=lgc+lgpn;
long double ans2=lgc+lgp1n;
long double ans=(long double)n*(exp(ans1)+exp(ans2));
for(int j=1;j<n;j++)
{
lgc+=log(n+j)-log(j);
ans1=lgc+lgpn+j*lgp1;
ans2=lgc+lgp1n+j*lgp;
ans+=(long double)(n-j)*(exp(ans1)+exp(ans2));
}
printf("Case %d: %.6Lf\n",t++,ans);
}
// fclose(stdout);
}
//10 0.400000
//100 0.500000
//124 0.432650
//325 0.325100
//532 0.487520
//2276 0.720000