HDU 4465 Candy--数学求期望
2014-10-19 20:33
393 查看
题目链接
题目大意 :两个盒子开始都有n块糖,每次从一个中拿糖的概率为p,求当一个盒子空时,另一个盒子中糖的数目期望
![](http://img.blog.csdn.net/20141019203654301)
很明显,200000太大了,不能直接排列组合。
然后需要一个快速排列组合函数:logC(m,n)
有了上面的算式之后,C(m,n)=exp(logC(m,n))
问题解决了吧。
但是其实问题没有解决,我们在比赛的时候想了一个小时,怎么处理double的上溢出和下溢出。。。
最后被函数中的log给提醒了。直接全部取log不就好了!
数值计算方法没学好啊
![](http://b.bst.126.net/common/portrait/west/preview/west17.gif)
所以算式变为
![](http://img7.ph.126.net/VkiIV2qVH5bqbcBrRiiEoA==/6597731672656468047.jpg)
法二:
题目分析 :不难得到公式: ans = 求和(i = 0~n)(n-i) * C(i, n + i) * ( (p ^ n* (1 - p) ^ i) + (p ^ i + (1 - p) ^ n)),
本题n上限为20000,组合数存不下故中间过程要用递推公式即an = an * n / (n + 1) *(n + i) / i * p这样还是会卡精度有点坑爹,可以采用一个很简单的技巧。见程序
题目大意 :两个盒子开始都有n块糖,每次从一个中拿糖的概率为p,求当一个盒子空时,另一个盒子中糖的数目期望
很明显,200000太大了,不能直接排列组合。
然后需要一个快速排列组合函数:logC(m,n)
<span style="font-size:14px;">f[0]=0; for(int i=1;i<=400002;i++) f[i]=f[i-1]+log(i*1.0); double logC(int m,int n){ return f[m]-f -f[m-n]; }</span>
有了上面的算式之后,C(m,n)=exp(logC(m,n))
问题解决了吧。
但是其实问题没有解决,我们在比赛的时候想了一个小时,怎么处理double的上溢出和下溢出。。。
最后被函数中的log给提醒了。直接全部取log不就好了!
数值计算方法没学好啊
![](http://b.bst.126.net/common/portrait/west/preview/west17.gif)
所以算式变为
![](http://img7.ph.126.net/VkiIV2qVH5bqbcBrRiiEoA==/6597731672656468047.jpg)
<span style="font-size:14px;">#include<cstdio> #include<cmath> double f[400005]; double logC(int m,int n){ return f[m]-f -f[m-n]; } int main(){ f[0]=0; for(int i=1;i<=400002;i++) f[i]=f[i-1]+log(i*1.0); int apple=1,n; double p,q; while(~scanf("%d",&n)){ scanf("%lf",&p); q=1-p; double ans=0; for(int k=0;k<=n;k++){ ans+=(n-k)*(exp(logC(n+k,k)+(n+1)*log(q*1.0)+k*log(p*1.0))+exp(logC(n+k,k)+(n+1)*log(p*1.0)+k*log(q*1.0))); } printf("Case %d: %.6f\n",apple++,ans); } return 0; }</span>
法二:
题目分析 :不难得到公式: ans = 求和(i = 0~n)(n-i) * C(i, n + i) * ( (p ^ n* (1 - p) ^ i) + (p ^ i + (1 - p) ^ n)),
本题n上限为20000,组合数存不下故中间过程要用递推公式即an = an * n / (n + 1) *(n + i) / i * p这样还是会卡精度有点坑爹,可以采用一个很简单的技巧。见程序
<span style="font-size:14px;">#include <cstdio> #include <cmath> int main() { int n, ca = 0; double p; while(scanf("%d %lf", &n, &p) != EOF) { double tmp1 = n, tmp2 = n ; // printf("tmp1 = %f tmp2 = %f\n", tmp1, tmp2); double ans1 = tmp1 * pow(1 - p, n + 1); double ans2 = tmp2 * pow(p, n + 1); int now = n; int re = n + 1; for(int i = 1; i < n; i++) { now = n - i; //系数 //递推公式 tmp1 *= 1.0 / (double)(now + 1) * p / i * (n + i) * now; tmp2 *= 1.0 / (double)(now + 1) * (1 - p) / i * (n + i) * now; //当tmp大于某个设定的值时让它乘p(或(1-p))来保证其数字不会暴精度 //关键技巧 while(tmp1 > n || tmp2 > n) { tmp1 *= (1 - p); tmp2 *= p; re--; } //因为每一项都要乘pow(1-p, n+1)或pow(p,n+1) //我们在此补上剩余未乘的p(或(1-p))的幂数即可 ans1 += tmp1 * pow(1 - p, re); ans2 += tmp2 * pow(p, re); // printf("tmp1 = %lf tmp2 = %lf \n", tmp1, tmp2); } printf("Case %d: %lf\n", ++ca, ans1 + ans2); } } </span>
相关文章推荐
- hdu 4465 Candy 数学期望 负二项分布与 数值计算技巧
- HDU 4465 Candy (数学期望)
- HDU 4465 Candy ( 数学期望 )
- HDU 4465 Candy 纯数学
- HDU 4465 Candy( 期望)
- hdu 4465 Candy 数学
- HDU 4465 - Candy(概率与数学优化)
- HDU 4465 - Candy(概率与数学优化)
- hdu 4465 Candy (概率期望)
- Hdu 4465 Candy (快速排列组合+概率)
- hdu 4465 Candy(概率公式+极大乘极小,4级)
- HDU 4808 数学 期望 积分
- HDU 4465 Candy 概率 (2012成都区域赛B题)
- hdu 4465 Candy
- HDU 4465 Candy
- uva1639 Candy 数学期望 对数处理精度
- hdu 4465 Candy(2012 ACM-ICPC 成都现场赛)
- hdu5984——Pocky(数学期望)
- hdu 4465 求期望(C(m,n)太大用log优化)
- 【数学期望】Candy, ACM/ICPC Chengdu 2012, UVa1639 【精度】