【Uva1639】概率 + 期望 + 对数处理精度

紫书上第十章的题
【最近看数学看的想吐】

紫书上讲的很好很详细,但是那个概率表达式C(2n - i, n) * p ^ (n + 1) * (1 - p) ^ (n - i) 我看不懂
后来弄懂了意思就是:如果设最后打开盒子1,盒子2里此时还剩i颗糖。那么在最后打开盒子发现没糖了之前,一共打开了 n + (n - i) 次盒子,在盒子1里面取了n颗糖,一共有多少种方案,每种方案里,打开盒子1(加上最后那一次一共n + 1次)的概率一共是p^(n + 1),打开盒子2的概率是(1 - p) ^ (n - i),乘起来就可以了。别忘了也要考虑最后打开盒子2的情况。

因为会损失精度,所以用对数处理。
c++有好多和对数有关的函数我以前竟然不知道,超级方便啊。
因为对数运算有 log (a * b) = log a + log b; log a^n = n * log a 的这些个运算律,所以把原来乘都变成了加,除都变成了减,要注意。

#include <cstdio>
#include <cmath>
#include <algorithm>
//#include <iostream>
using namespace std;

const int MAXN = 2e5 + 5;

long double logC[MAXN * 2];

long double C(int m, int n)
{
    return logC[m] - logC[n] - logC[m - n];
}

int main()
{
    int n;
    double p;

    //logC[1] = 1;
    for (int i = 1; i <= MAXN * 2; i++)
    {
        logC[i] = logC[i - 1] + log(i);
    }

    int ka = 0;
    //scanf("%d", &ka);
    //while ((scanf("%d %f"), &n, &p) == 2)
    while (scanf("%d %lf", &n, &p) == 2)
    {
        ka++;
        long double sum = 0.0;
        for (int i = 1; i <= n; i++)
        {
            long double v1 = C(2 * n - i, n) + (n + 1) * log(p) + (n - i) * log(1 - p);
            long double v2 = C(2 * n - i, n) + (n + 1) * log(1 - p) + (n - i) * log(p);
            sum += (double)i * (exp(v1) + exp(v2));
        }

        printf("Case %d: %.6Lf\n", ka, sum);
    }
    return 0;
}

我概率和期望几乎一点不会,这么一道很好写的水题我也是不大会写。慢慢来吧。前面说的都是瞎想出来的,找学数学的姐姐讲了讲但是写的时候好像都忘干净了。如果有哪里有错误希望一定告诉我qwq感谢!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值