UVa 1639 Candy (数学期望+组合数学+高精度存储)

Posted dwtfukgv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa 1639 Candy (数学期望+组合数学+高精度存储)相关的知识,希望对你有一定的参考价值。

题意:有两个盒子各有n个糖,每次随机选一个(概率分别为p,1-p),然后吃掉,直到有一次,你打开盒子发现,没糖了!

输入n,p,求另一个盒子里糖的个数的数学期望。

析:先不说这个题多坑,首先要用long double来实现高精度,我先用的double一直WA,后来看了题解是用long double,

改了,可一直改不对,怎么输出结果都是-2.00000,搞了一晚上,真是无语,因为我输入输出数据类型是long double,

结果一直不对 ,可能是我的编译器是C89的吧,和C语言,输入输出格式不同,但是我改成C99也不对。。。

最后一看题解明白了,输入输出不需要那么高的精度,用double就足够了,可算是废了一晚上的时间。。。悲惨

下面分析这个题:

首先我们不知道最后打开的是哪个盒子,所以我们需要都考虑,当最后打开是第一个时,此时另一个有i个,那么在些之前一定是打开过

n+(n-i)次盒子,其中n次是第一个盒子,n-i次是第二个盒子,这是明显是一个二项分布,所以概率为C(2n-i, n)pn+1(1-p)n-i,这个地方

一定要注意是n+1,不是n,因为我们也要把最后一次的算上。

这个式子很明显是正确的,但是有一个大问题,那就是C(2n-i, n)这数据实在是太大了(因为n太大了),肯定无法用整形保存,

甚至无法用浮点保存,所以我们对它进行高精度处理,大数选的是对数法,令v1(i) = ln(C(2n-i, n)) + (n+1)ln(p) + (n-i)ln(1-p).

这个地方一定是加减,不是乘除,这是对数,刚开始又忘了,结果一直不对。。。

那么最后打开的是第一个盒子数学期望是ev1(i)

同理最后一个打开的是第二个盒子时,对数为v2(i) = ln(C(2n-i, n)) + (n+1)ln(1-p) + (n-i)ln(p),概率为ev2(i)

那么总的数学期望是sum{i*(ev1(i)+ev2(i))}((ev1(i)+ev2(i))这个是概率)。

这个题需要高精度,所以用long double来存储,真是坑。。。。很难想到。

代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;
typedef long double LD;
const int maxn = 400000 + 10;
LD log_ld[maxn];

void init(){
    log_ld[1] = 0.0;
    for(int i = 2; i < maxn; ++i)
        log_ld[i] = log_ld[i-1] + (LD)log((LD)i);
}

double solve(int n, LD p){
    LD ans = 0.0;
    for(int i = 1; i <= n; ++i)
        ans += (LD)i * exp(log_ld[2*n-i] - log_ld[n] - log_ld[n-i] + (LD)(n+1)*log(p) + (LD)(n-i)*log(1.0-p));

    for(int i = 1; i <= n; ++i)
        ans += i * exp(log_ld[2*n-i] - log_ld[n] - log_ld[n-i] + (LD)(n+1)*log(1.0-p) + (LD)(n-i)*log(p));
    return ans;
}

int main(){
//    freopen("in.txt", "r", stdin);
    int n, kase = 0;
    double p;
    init();

    while(~scanf("%d %lf", &n, &p)){
        double ans = solve(n, p);
        printf("Case %d: %.6f\n", ++kase, ans);
    }
    return 0;
}

 

以上是关于UVa 1639 Candy (数学期望+组合数学+高精度存储)的主要内容,如果未能解决你的问题,请参考以下文章

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

UVa 12230 Crossing Rivers (数学期望水题)

Uva12230Crossing Rivers (数学期望)

UVa 12230 - Crossing Rivers(数学期望)

UVa 12230 Crossing Rivers (数学期望)

动态规划数学期望/概率DP/期望DP详解