混沌DM

DM Hunter

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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 }
posted on 2012-11-17 23:46  混沌DM  阅读(950)  评论(0编辑  收藏  举报