HDU 4465 Candy(组合+log优化)

题目大意:给你两个罐子,里面有糖果每次只能从一个罐子里面取一个糖果,打开A的概率为p,问当一个罐子取完之后,另一个罐子剩糖果的期望是多少。

我们可以知道最少是取第n+1次的时候才会有一个罐子为空,我们可以推出组合公式:

(n-k)*C(n+k, k)*((1-p)^(n+1)*p^k+(1-p)^k*p^(n+k));0 <= k && k <= n-1。

求一个和就是所有的组合情况了,但是组合数很大我们可以用log来进行优化。

我们已知:C(n,m) = m!/n!/(m-n)! = log(m!)/log(n!)/log(m-n)。

m!= 1*2*……*m = log(1)+log(2)+……+log(m).

先打表在直接求就可以了啊。

C(m,n)=exp(logC(m,n))

Candy

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2229    Accepted Submission(s): 958

Special Judge

Problem 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.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

Source

2012 Asia Chengdu Regional Contest

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <time.h>
#include <stack>
#include <map>
#include <set>
#define eps 1e-8
///#define LL long long
#define LL __int64
#define INF 0x3f3f3f
#define PI 3.1415926535898
#define mod 1000000007

using namespace std;

const int maxn = 505000;

double f[maxn];
double logc(int m, int n)///C(n,m) = m!/n!/(m-n)!
{
    return f[m]-f[n]-f[m-n];
}

int main()
{
    f[0] = 0;
    for(int i = 1; i <= 400005; i++) f[i] = f[i-1]+log(i*1.0);
    int Case = 1;
    int n;
    double p;
    while(~scanf("%d %lf",&n, &p))
    {
        double sum = 0.0;
        for(int k = 0; k < n; k++)
        {
            ///sum += (n-k)*C(n+k, k)*((1-p)^(n+1)*p^k+(1-p)^k*p^(n+k));
            sum += 1.0*(n-k)*(exp(logc(n+k, k)+(n+1)*1.0*log(1.0-p)+k*1.0*log(p*1.0)) +  exp(logc(n+k, k)+(n+1)*1.0*log(p*1.0)+k*1.0*log(1.0-p)));
        }
        printf("Case %d: %.6lf\n",Case++, sum);
    }
}
时间: 2024-12-23 14:51:08

HDU 4465 Candy(组合+log优化)的相关文章

Hdu 4465 Candy (快速排列组合+概率)

题目链接: Hdu 4465 Candy 题目描述: 有两个箱子,每个箱子有n颗糖果,抽中第一个箱子的概率为p,抽中另一个箱子的概率为1-p.每次选择一个箱子,有糖果就拿走一颗,没有就换另外一个箱子.问换箱子的时候,另外一个箱子中剩下糖果的期望值. 解题思路: 注意题目描述,其中任意一个箱子没有糖果,另一个箱子中剩下糖果个数的期望,而不是第一个箱子没有糖果.不是把其中一个箱子取空时,另一个箱子剩下糖果的期望,而是其中一个箱子取空再换另外一个箱子时,这个箱子的期望. 可以根据期望性质画出公式:an

hdu 4465 Candy 2012 成都现场赛

1 /** 2 对于大数的很好的应用,,缩小放大,,保持精度 3 **/ 4 #include <iostream> 5 #include <cmath> 6 #include <algorithm> 7 #include <cstdio> 8 using namespace std; 9 10 int main() 11 { 12 double n,p; 13 int cnt =1; 14 while(cin>>n>>p){ 15

hdu 4465 Candy (快速排列组合 )

Candy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2115    Accepted Submission(s): 910 Special Judge Problem Description LazyChild is a lazy child who likes candy very much. Despite being ve

[概率+对数优化] hdu 4465 Candy

题意: 给两个盒子里面都有n个糖果,每次从第一个盒子里拿糖果的概率是p,另一个是1-p 问当拿完一个盒子时,另一个盒子还有多少糖果的期望. 其中有一点就是,当她打开盒子发现是空的时候 会去打开另一个盒子在同一天. 思路: 期望公式很好推: 但是推完就会出现各种溢出问题 所以要用对数优化 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath"

HDU 4465 Candy

Candy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2520    Accepted Submission(s): 1100Special Judge Problem DescriptionLazyChild is a lazy child who likes candy very much. Despite being very

HDU 1059 多重背包+二进制优化

Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 16909    Accepted Submission(s): 4729 Problem Description Marsha and Bill own a collection of marbles. They want to split the collection

HDU 3507 Print Article 斜率优化

Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 4810    Accepted Submission(s): 1451 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antique

HDU 3507 单调队列 斜率优化

斜率优化的模板题 给出n个数以及M,你可以将这些数划分成几个区间,每个区间的值是里面数的和的平方+M,问所有区间值总和最小是多少. 如果不考虑平方,那么我们显然可以使用队列维护单调性,优化DP的线性方法来做,但是该题要求的是区间和的平方,于是要转换单调的计算方法为斜率,也就是凸线. 其他就是最基本的单调DP /** @Date : 2017-09-04 15:39:05 * @FileName: HDU 3507 单调队列 斜率优化 DP.cpp * @Platform: Windows * @

hdu 5291 Candy Distribution(dp)

题目链接:hdu 5291 Candy Distribution 每次先计算出dp[0],然后根据dp[0]的数值可以用o(1)的复杂度算出dp[1],以此类推.总体复杂度为o(200 * 80000),可以接受. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 80000; const int maxm = 205; cons