Uva1639(概率期望/对数处理避免丢失精度)

Uva1639

题意:

有两个盒子各有n个糖果(n<=200000),每天随机选择一个:选第一个盒子的概率是p(0 ≤ p ≤ 1),第二个盒子的概率为1-p,然后吃掉其中的一颗。直到有一天,随机选择一个盒子打开一看,没糖了!现在请你计算另一个盒子里剩下的糖果数量的期望值。

解法:

我们假设到第n天的时候取得是第1个盒子的糖,此时第2个盒子有i颗糖,则在此之前打开了n+(n-i)次盒子, 其中n次打开了第一个盒子,(n-i)次打开了第二个盒子,则概率是C(2n-i,n)*p^(n+1)*(1-p)^n-i。

由于n高达20w,所以二次项系数会非常大,而后面的概率会非常小,所以如果直接计算会爆精度,所以这里我们用求对数的方法进行计算

 1 #include<iostream>
 2 #include<cmath>
 3 using namespace std;
 4 typedef long double lb;
 5 const int maxn = 2e5 + 5;
 6 long double logF[2 * maxn + 66];
 7
 8 void generate() {
 9     //预处理出n!的log值
10     logF[0] = 0;
11     for (int i = 1; i <= maxn; i++)
12         logF[i] = logF[i - 1] + log(i);
13 }
14 // C(n,m) = n!/(m!(n-m)!)
15 long double logC(int n, int m) {
16     return logF[n] - logF[m] - logF[n - m];
17 }
18
19 int main() {
20     int n; double p;
21     generate();
22     int kase = 1;
23     while (scanf("%d%lf", &n, &p)!=EOF) {
24         double ans = 0;
25         for (int i = 0; i <= n; i++) {
26             long double v1 = logC(2 * n - i, n) + (n + 1)*log(p) + (n - i)*log(1 - p);
27             long double v2 = logC(2 * n - i, n) + (n + 1)*log(1 - p) + (n - i)*log(p);
28             ans += (i*(exp(v1) + exp(v2)));
29         }
30         printf("Case %d: %.6lf\n", kase++, ans);
31     }
32     return 0;
33 }

原文地址:https://www.cnblogs.com/romaLzhih/p/9515177.html

时间: 2024-10-13 23:05:30

Uva1639(概率期望/对数处理避免丢失精度)的相关文章

UVa1639 - Candy(期望+对数精度处理)

注意题意是开始两个盒子各有n个糖果,等吃完就只有两种情况,盒子1没了,或者盒子2没了. 这完全是个求概率期望的数学问题.借用二项分布公式: P(ξ=K)= C(n,k) * p^k * (1-p)^(n-k), 其中C(n, k) = n!/(k! * (n-k)!)注意!:第二个等号后面的括号里的是上标,表示的是方幂. 得出第i次打开盒子1没糖的概率C(2n-1,n)p^(n+1)(1-p)^(n-i) 得出第i次打开盒子2没糖的概率C(2n-1,n)(1-p)^(n+1)p^(n-i) 第i

hdu 4586 (概率+期望)

http://acm.hdu.edu.cn/showproblem.php?pid=4586 大致题意:有一个骰子有n个面,掷到每一个面的概率是相等的,每一个面上都有相应的钱数.其中当你掷到m个面之一时,你有多掷一次的机会.问最后所得钱数的期望. 思路:设投掷第一次的期望是p,那么第二次的期望是m/n*p,第三次的期望是 (m/n)^2*p......第N次的期望是(m/n)^(N-1)*p. 那么这些期望之和便是答案.之前也是想到这,但不知道如何处理无限的情况.当时脑卡了,这不是赤裸裸的等比数

OI队内测试一【数论概率期望】

版权声明:未经本人允许,擅自转载,一旦发现将严肃处理,情节严重者,将追究法律责任! 测试分数:110 本应分数:160 改完分数:200 T1: 题解:推出了一个初始式子但是n的4分之3次方 忘了合并[实际上是没发现]本来应有60分的,但是忘记开long long 只有30分 因为一些公式不好写出来就直接截图题解吧! T2: 题解:很简单的概率期望,算出每个点被选的概率,然后在上树状数组或者线段树求逆序队,但是我只有80分,为什么解法不行?NO NO 你还是太年轻我只是线段树数据范围开小了!![

uvalive 7331 Hovering Hornet 半平面交+概率期望

题意:一个骰子在一个人正方形内,蜜蜂在任意一个位置可以出现,问看到点数的期望. 思路:半平面交+概率期望 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdlib> 6 #include<string> 7 #include<cmath> 8 #include<vector&

【BZOJ-1419】Red is good 概率期望DP

1419: Red is good Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 660  Solved: 257[Submit][Status][Discuss] Description 桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元.可以随时停止翻牌,在最优策略下平均能得到多少钱. Input 一行输入两个数R,B,其值在0到5000之间 Output 在最优策略下平均能得到多少钱

Lightoj 1027 概率期望

Problem: 概率期望 Analyse: 非常经典的带有递归实现,的方程期望式子. E为期望,z为正数个数,zp为正数平均值,f为负数个数,fp为负数平均值. z?zpn+f?fp+En=E /**********************jibancanyang************************** *Author* :jibancanyang *Created Time* : 五 5/ 6 23:58:46 2016 *File Name* : .cpp **Code**:

【转】为何浮点数可能丢失精度

转自铅笔 为何浮点数可能丢失精度?浮点十进制值通常没有完全相同的二进制表示形式. 这是 CPU 所采用的浮点数据表示形式的副作用.为此,可能会经历一些精度丢失,并且一些浮点运算可能会产生意外的结果. 导致此行为的原因是下面之一:1.十进制数的二进制表示形式可能不精确.2.使用的数字之间类型不匹配(例如,混合使用浮点型和双精度型). 为解决此行为,大多数程序员或是确保值比需要的大或者小,或是获取并使用可以维护精度的二进制编码的十进制 (BCD) 库. 详细剖析:浮点型运算为什么会造成精度丢失?1.

hdu4405--Aeroplane chess+概率期望dp

首先推荐一篇很好的如何概率期望问题的入门文章:点击打开链接 昨天比赛的时候面对这道题的第一想法是依照数学期望的定义来做,即依次求出某个点扔i次骰子能到达n点的概率,然后由期望的定义就可以求出答案了.但显然这在程序上是不可能实现的. 今天看了那篇文章后才知道自己的想法是大错特错的;求解这种问题应该采用一种递推的思路,即每次只考虑一次转移后当前状态的期望,然后我们依次考虑每个节点就可以得到一个方程组,然后就只需要求解这个方程组就行了. 当然对于如何求解这个方程组,我们可以采用高斯消元法,当然如果这个

CF148D--Bag of mice+概率期望dp

第一道概率期望dp:) 其实和一般的dp也差不多,只要状态选好就行了. 定义dp[i][j]表示还剩i只白老鼠j只黑老鼠时候公主赢得概率. 则:1.公主选白老鼠,直接赢,概率:i/(i+j) 2.公主选黑老鼠 1)龙选黑老鼠,逃走黑老鼠:概率:j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2) 2)  龙选黑老鼠,逃走白老鼠:概率:j/(i+j)*(j-1)/(i+j-1)*i/(i+j-2) 3) 龙选白老鼠,这样公主是必输的,不用考虑 然后dp[i][j]等于以上概率之和