Candy

来源:互联网 发布:编程什么意思 编辑:程序博客网 时间:2024/06/03 10:21

Description

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.400000100 0.500000124 0.432650325 0.325100532 0.4875202276 0.720000
 

Sample Output

Case 1: 3.528175Case 2: 10.326044Case 3: 28.861945Case 4: 167.965476Case 5: 32.601816Case 6: 1390.500000
本题题意是给你两个罐子,每个里面都有n个糖,现在LazyChild每天要随机从一个里面拿出一个糖,且选择其中一个罐子的概率为p,问当他某天打开罐子时发现里面没有糖了,问另外一个罐子中糖果数的期望。
用一个二元组(x,y)表示两个袋子中剩余的糖的数量,P((x,y))表示达到这个状态的概率,那么对于答案有直接贡献的状态就是(0,y)和(x,0)两种。第一种状态对于答案的贡献是P((0,y))*y*p,第二种是P((x,0))*x*(1-p)。
这个式子中唯一的未知量是P,P的求法如下:
拿(0,y)为例,一共拿了n+(n-y)次糖了,第一个袋子被拿n次,第二个袋子被拿(n-y)次,那概率显然就是 C(n+n-y,n) * (p^n) * ((1-p)^(n-y))//拿法方案数*对应位置都拿对糖果的概率
直接顺推组合数和概率即可,但是在计算过程中会遇到问题,组合数和概率的指数都会达到n的级别,而n是10^5的,已经完爆了C++的所有数据类型
对数转换来巧妙的避免这些问题,取对数之后把乘法变成加法,答案再exp倒回来
#include<cstdio>#include<cmath>using namespace std;typedef long long LL;int N;double P;int main(){    int c=1;    while(scanf("%d%lf",&N,&P)!=EOF)    {   double C=log(1);        double logp1 = log(P);        double logp2 = log(1-P);        double lp1=(N+1)*logp1;        double lp2=(N+1)*logp2;        double ans=0;        for(int i=N;i>=0;--i)        {   double lp1i = (N-i)*logp2;            double lp2i = (N-i)*logp1;            double t1 = C+lp1+lp1i,t2 = C+lp2+lp2i;            ans += i*(exp(t1)+exp(t2));            C = C+log(double(2*N-i+1))-log(double(N-i+1));        }        printf("Case %d: %.6lf\n",c++,ans);    }    return 0;}


0 0
原创粉丝点击