题意:两个箱子,每个箱子有n颗糖,每次有p的概率拿1号箱子的一颗糖出来(有1-p的概率拿2号箱子的一颗糖出来),问当打开某个箱子为空的时候,另一个箱子的期望糖的数量是多少
题解:枚举另一个箱子的糖的数量乘以可能性就是答案,一部分是:C(i,n+i) *p^(n+1) *(1-p)^i *(n-i)(剩下n-i颗糖)
注意可能是1号箱子糖拿完了,也可能是2号箱子糖拿完了,然后就是拿完了的那个箱子查看的次数不是n,而是n+1次;接着要注意精度,需要使用对数(e^In(x)=x)与long double
#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<vector> #include<string> #include<cstdio> #include<cstring> #include<iomanip> #include<stdlib.h> #include<iostream> #include<algorithm> using namespace std; #define eps 1E-8 /*注意可能会有输出-0.000*/ #define sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型 #define cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化 #define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0 #define mul(a,b) (a<<b) #define dir(a,b) (a>>b) #define e 2.718281828 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const int Inf=1<<28; const ll INF=1LL<<60; const double Pi=acos(-1.0); const int Mod=1e9+7; const int Max=400010; ld logesum[Max];//预处理 void Init(int n) { logesum[0]=0; for(int i=1; i<n; ++i) { logesum[i]=logesum[i-1]+log((ld)i); } return ; } ld Jud(int n,int i,ld p) { return (n+1)*log(p)+i*log(1-p)+logesum[n+i]-logesum[i]-logesum[n]; } double Solve(int n,ld p) { double ans=0.0; for(int i=0; i<n; ++i) { ans+=(n-i)*exp(Jud(n,i,p)); ans+=(n-i)*exp(Jud(n,i,1-p)); } return ans; } int main() { int n,coun=0; double p; Init(Max); while(~scanf("%d %lf",&n,&p)) { printf("Case %d: %.6f ",++coun,Solve(n,p)); } return 0; }