[水题日常]UVA11181 条件概率(Probability|Given)

本文详细解析了一道涉及概率论的购物问题,通过条件概率公式和枚举算法,求解了在已知部分人购物的情况下,每个人实际购物的概率。文章包括了具体的数学推导过程和C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 话说好久没写blog了
  • 好好学概率论的第一天,这题一开始完全不会写,列出个条件概率的公式就傻了,后来看着lrj老师的书附带的代码学着写的…
  • 因为我比较弱智 一些比较简单的东西也顺便写具体点或者是按照书上的说法写了(所以这一篇可能还会更偏向于笔记的样子…)…如果觉得没必要看的话可以直接跳下去


题意:\(n\)个人准备去买东西,第\(i\)个人买东西的概率是\(P_i\),买完东西之后你得知一共有\(r\)个人买了东西,求每个人实际买了东西的概率。(\(1<=n<=20\)

  • \(r\)个人买了东西的事件为\(E\),第\(i\)个买东西的事件为\(E_i\),则我们要求的是\(P(E_i|E)\)
  • 条件概率公式告诉我们\(P(E_i|E)=\frac {P(E_i E)}{P(E)}\)\(P(E_i E)\)表示事件\(E_i\)\(E\)同时发生的概率)
  • 先来看看\(P(E)\)怎么求?首先注意到这题的\(n\)只有20我们直接枚举所有购买的情况,用一个数组\(buy[1..n]\)记录每个人是否买了东西(比如1表示买0表示没买)
  • 直接\(dfs\)所有情况,枚举完一种有\(r\)个人购买的情况之后给\(P(E)\)加上这一种情况的概率:\(\prod_{i\in X} P_i\cdot\prod_{j\in Y} (1-P_j)\)(这里用\(X\)来表示所有买东西的人的集合,\(Y\)表示没有买东西的人的集合)(不要被这个东西吓到!,想想看假如3个人里有两个人买了东西,分别是第一个人和第三个人,那么这一种情况的概率是不是就是\(P_1\cdot(1-P_2) \cdot P_3\)?!)
  • (上面那一串式子直接在搜的时候就顺便求出来)
  • 啃完了硬骨头(对我来说是这样的)我们再来看看\(P(E_i E)\),跟上面的方法一样,枚举的时候顺便记录数组\(buy[]\),枚举完一种买\(r\)个东西的情况之后扫一遍\(buy[]\),如果记\(sum[i]\)表示最后的\(P(E_i E)\)的话,那样如果第\(i\)个人买了就给\(sum[i]\)加上上面那一串式子
  • 最后对于每个询问输出\(sum[i]/P(E)\)就好啦~

最后还是贴一下代码吧(然而这个只是学着书上附带的代码自己打了一遍(写的应该还比较挫
要往下拉的请慎重!~

#include<cstdio>
#include<cstring>
int kase,n,r;
bool buy[25];double p[25],sum[25];
inline void dfs(int d,int c,double prob)
{
    if(c>r||d-c>n-r+1)return;
    if(d==n+1)
    {
        sum[n+1]+=prob;
        for(int i=1;i<=n;i++)if(buy[i])
            sum[i]+=prob;
        return;
    }
    buy[d]=0;
    dfs(d+1,c,prob*(1-p[d]));
    buy[d]=1;
    dfs(d+1,c+1,prob*p[d]);
}
int main()
{
    while(scanf("%d%d",&n,&r)==2&&(n||r))
    {
        memset(sum,0,sizeof(sum));
        memset(buy,0,sizeof(buy));
        for(int i=1;i<=n;i++)scanf("%lf",&p[i]);
        dfs(1,0,1.0);
        printf("Case %d:\n",++kase);
        for(int i=1;i<=n;i++)printf("%.6lf\n",sum[i]/sum[n+1]);
    }return 0;
}

这里直接顺便用\(sum[n+1]\)表示了\(P(E)\)
顺便,可以注意一下这里\(dfs\)

    if(c>r||d-c>n-r+1)return;

第一个就是判断买的人有没有超过\(r\),超过的话直接剪枝,第二个判断这条路径上没有买的人是否超过应该没有买的人,超过的话也剪掉。(这样其实也保证了\(d=n+1\)\(c=r+1\)


如果有问题欢迎在评论区指出~

转载于:https://www.cnblogs.com/yoooshinow/p/7506330.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值