1639 - Candy

Time limit: 3.000 seconds

1639 Candy
LazyChild is a lazy child who likes candy very much. Despite being very young, he has two large candy boxes, each contains n candies initially. Everyday he chooses one box and open it. He chooses the first box with probability p and the second box with probability (1−p). For the chosen box, if there are still candies in it, he eats one of them; otherwise, he will be sad and then open the other box. He has been eating one candy a day for several days. But one day, when opening a box, he finds no candy left. Before opening the other box, he wants to know the expected number of candies left in the other box. Can you help him?
Input
There are several test cases. For each test case, there is a single line containing an integer n (1 ≤ n ≤ 2×105) and a real number p (0 ≤ p ≤ 1, with 6 digits after the decimal). Input is terminated by EOF.
Output
For each test case, output one line ‘Case X: Y ’ where X is the test case number (starting from 1) and Y is a real number indicating the desired answer. Any answer with an absolute error less than or equal to 10−4 would be accepted.
Sample Input
10 0.400000 100 0.500000 124 0.432650 325 0.325100 532 0.487520 2276 0.720000
Sample Output
Case 1: 3.528175 Case 2: 10.326044 Case 3: 28.861945 Case 4: 167.965476 Case 5: 32.601816 Case 6: 1390.500000

根据期望的定义,不妨设最后打开第1个盒子,此时第2个盒子有i颗,则这之前打开过n+n-i次盒子,其中有n次取得时盒子1,其余n-i次取得是盒子2,概率为C(2n - i, n)p^(n+1)*(1-p)^(n-i)。注意p的指数是n+1,因为除了前面打开过n次盒子1之外,最后又打开了以此,因此C(2n-i, n)可能非常大,而p^(n+1)和(1-p)^(n-i)却非常接近0.如果分别计算这三项再乘起来,会损失很多精度。所以利用对数处理,设v1(i)=ln(C(2n-i, n))+(n+1)ln(p)+(n-i)ln(1-p),则“最后打开第1个盒子”对应的数学期望为e^v1(i)。

同理,当最后打开第2个盒子,对数为v2(i)=ln(C(2n-i, n))+(n+1)ln(1-p)+(n-i)ln(p),概率为e^v2(i)。根据数学期望的定义,答案为sum{ i ( e^v1(i) + e^v2(i) ) }.

ps: long double 的使用linux下,%Lf与%llf皆可,%lf不可

此题需用long double

#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
#define ll long long
#define _cle(m, a) memset(m, a, sizeof(m))
#define repu(i, a, b) for(int i = a; i < b; i++)
#define MAXN 200005
long double LogB[ * MAXN] = {0.0};
int main()
{
repu(i, , * MAXN) LogB[i] = LogB[i - ] + log(i);
int n, kase = ;
double p;
while(~scanf("%d%lf", &n, &p))
{
double e = 0.0;
if(p == 0.0 || p == 1.0) e = n;
else
{
long double v1, v2;
long double logp = log(p), log_p = log(1.0 - p);
repu(i, , n + )
{
long double t = LogB[ * n - i] - LogB[n] - LogB[n - i];
v1 = t + (n + ) * logp + (n - i) * log_p;
v2 = t + (n - i) * logp + (n + ) * log_p;
e += (exp(v1) + exp(v2)) * (i);
} }
printf("Case %d: %.6lf\n", ++kase, e);
}
return ;
}

uva 1639--精度处理方法之取对数(uva 1639)的更多相关文章

  1. 【每日一题】 UVA - 11809 Floating-Point Numbers 阅读题+取对数处理爆double

    https://cn.vjudge.net/problem/UVA-11809 题意:很长orz 题解:算一下输入范围,发现用double是读不进来的,在这里wa了半天,(double 1e300  ...

  2. 【取对数】【哈希】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem J. Bobby Tables

    题意:给你一个大整数X的素因子分解形式,每个因子不超过m.问你能否找到两个数n,k,k<=n<=m,使得C(n,k)=X. 不妨取对数,把乘法转换成加法.枚举n,然后去找最大的k(< ...

  3. hdu 1568 (log取对数 / Fib数通项公式)

    hdu 1568 (log取对数 / Fib数通项公式) 2007年到来了.经过2006年一年的修炼,数学神童zouyu终于把0到100000000的Fibonacci数列 (f[0]=0,f[1]= ...

  4. poj2661 Factstone Benchmark(大数不等式同取对数)

    这道题列出不等式后明显是会溢出的大数,但是没有必要写高精度,直接两边取对数(这是很简明实用的处理技巧)得: log2(n!)=log2(n)+log2(n-1)+...+log2(1)<=log ...

  5. HDU3666 THE MATRIX PROBLEM (差分约束+取对数去系数)(对退出情况存疑)

    You have been given a matrix C N*M, each element E of C N*M is positive and no more than 1000, The p ...

  6. 【转载】C#使用Except方法求取两个List集合的差集数据

    在C#语言的编程开发中,针对List集合的运算有时候需要计算两个List集合的差集数据,集合的差集是取在该集合中而不在另一集合中的所有的项.A集合针对B集合的差集数据指的是所有在A集合但不在B集合的元 ...

  7. 取对数求阶乘位数——lightoj1045

    /* 求 n! 在base进制下的位数 取对数,用换底公式,预处理对数前缀和 b^x = n! x = log_b(n!) = log_10(n!)/log_10(b) 对x向上取整即可 */ #in ...

  8. 【取对数+科学计数法】【HDU1060】 N^N

    Leftmost Digit Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...

  9. java中小数的处理:高精度运算用bigDecimal类,精度保留方法,即舍入方式的指定

    一. 计算机的小数计算一定范围内精确,超过范围只能取近似值: 计算机存储的浮点数受存储bit位数影响,只能保证一定范围内精准,超过bit范围的只能取近似值. java中各类型的精度范围参见:http: ...

随机推荐

  1. vim功能使用

    转自:http://blog.csdn.net/xiajun07061225/article/details/7039413 vi与vim vi编辑器是所有Unix及Linux系统下标准的编辑器,他就 ...

  2. .NET/C# 使用Stopwatch测量运行时间

    Stopwatch类:http://msdn.microsoft.com/zh-cn/library/system.diagnostics.stopwatch(v=vs.100).aspx 常用属性和 ...

  3. Doragon Kuesuto 1.0

    #include<stdio.h> #include<stdlib.h> #include<time.h> int main() { ; ; ; int actio ...

  4. Android生命周期和Service生命周期

    android生命周期 运行:oncreate → onstart → onresume暂停:onresume → onpause:再次运行:onresume停止:onpause → onstop → ...

  5. Mysql插入数据的时候,中文乱码问题的解决

    如果在Mysql中插入数据的时候,没有特定指定编码,可能会产生一系列的问题,例如,如果用insert语句的时候,可能提示incorrect values,等...究其原因,实际上无非是要让数据库和表中 ...

  6. Linux系统的介绍

    一.linux的特点: Linux是一个开源(源代码公开),免费的操作系统,其稳定性,安全性(也会有病毒,但因为linux是开源的,所以一旦有病毒就会有人去搞定它),处理多并发(月,NEC(日本电气股 ...

  7. 【c++】读写txt

    #include<iostrea> #include<fstream> int main() { ofstream fout;// 创建一个ofstream对象 fout.op ...

  8. VR应用里面的Photogrammetry技术是什么

    http://www.manew.com/thread-49556-1-1.html 具体使用 http://www.didayin.com/archives/632 软件下载 http://labs ...

  9. java String与Byte[]和String 与InputStream转换时注意编码问题。。。

    前一段日子,我在做rsa加密和通过http get方式获取验证码图片通过BitmapFactory创建bitmap 出现了一系列的问题. 通过一系列的调试,发现有些问题原来是在进行String 与By ...

  10. 在centos6.5中安装mysql5.7

    简介 博主最近在研究mysql的读写分离和主从复制,一台master和两台slave,三台机器在同一个局域网中,首先就就要在centos6.5中安装mysql5.7.好了,废话不多说,接下来进入正题. ...