http://acm.hdu.edu.cn/showproblem.php?pid=4465
本题题解非博主原创。
是队里的神牛YCL在比赛的时候灵光一闪想到的,目前依旧只能无尽的膜拜OOOOrz
首先公式是很好推的
for(int i=0;i<=n;i++) ans+=C(n+i,n)*(p^(n+1) * (1-p)^i + (1-p)^(n+1) * p^i)
目前依然不知道官方是怎样做到不溢出。。基本网上看到的题解都是在想办法解决中间过程溢出的问题,这里提供下队里YCL神牛比赛时灵光一闪的做法。。
看代码应该就能看懂了。
1 #include<cstdio> 2 #include<cmath> 3 #include<cstdlib> 4 #include<algorithm> 5 using namespace std; 6 int main() 7 { 8 int n,C=0; 9 double p,c,p1,p2,s1,s2,ans; 10 while(~scanf("%d%lf",&n,&p)){ 11 ans=c=0.0; 12 p1=log(p); 13 p2=log(1-p); 14 s1=(n+1)*p1; 15 s2=(n+1)*p2; 16 for(int i=0;i<n;i++){ 17 if(c+s1 > -30 || c+s2 > -30)ans+=(exp(c+s1)+exp(c+s2))*(n-i); 18 c+=log(n+i+1)-log(i+1); 19 s1+=p2; 20 s2+=p1; 21 } 22 printf("Case %d: %lf\n",++C,ans); 23 } 24 return 0; 25 }