uva 11181 : Probability | Given (条件概率)

博客围绕有n个人去超市,已知r人买东西,求每个人实际买东西概率的问题展开。运用条件概率公式P(Ai | B) = P(Ai B) / P(B),结合全概率公式计算。通过枚举所有情况得出P(B)和第i个人买东西的概率,答案为两者相除,具体实现可用dfs枚举r元子集。

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

题面大意:有n个人去超市,第i个人有pi的概率买东西。逛完以后你得知有r个人买了东西。根据这一信息,请计算每个人实际买了东西的概率。输入n (1 <= n <= 20) 和 r (0 <= r <= n),输出每个人实际买了东西的概率。

解法:条件概率,设第i个人买了东西为事件Ai,r个人买了东西为事件B,要求的是P(Ai | B) = P(Ai B) / P(B) (条件概率公式),注意这是离散型但不是古典型,不能直接用样本点数除以样本空间,因为基本事件概率不相同。要运用全概率公式,假设有4个人,其中2个人买了东西,所有的情况是1100,1010,1001,0110,0101,0011(1表示买了东西,0表示没买东西)。这些事件为B事件的所有情况,1100的概率就是 : p1 * p2 * ( 1 - p3) * (1 - p4),P(B)就是这些概率的总和,设为tot。第i个人有买东西的概率是所有第i位为1的概率的总和,设为sumi。
答案就是sumi / tot。

具体实现:可以用dfs枚举r元子集。

#include<bits/stdc++.h>
using namespace std;
int n,r;
const int maxn = 1e3 + 10;
double p[maxn];
double ans[maxn];
int vis[maxn];
double res;
void dfs(int cur,int num) {
	if(num == 0) {
    	double tmp = 1;
    	for(int i = 1; i <= n; i++) {
    	    if(vis[i]) tmp *= p[i];
    	    else tmp *= (1 - p[i]); 
    	}
    	for(int i = 1; i <= n; i++) {
    	    if(vis[i]) ans[i] += tmp;
    	}
    	ans[0] += tmp;
    	return ;
    }
    if(cur > n) return;
 	vis[cur] = 1;
    dfs(cur + 1,num - 1);
    vis[cur] = 0;
    dfs(cur + 1,num);
}
int main() {
	int ca = 0;
    while(scanf("%d%d",&n,&r)) {
    	if(n == 0 && r == 0) 
			break;
        for(int i = 0; i <= 25; i++) ans[i] = 0;
        memset(vis,0,sizeof(vis));
        for(int i = 1; i <= n; i++)
            scanf("%lf",&p[i]);
        dfs(1,r);
        printf("Case %d:\n",++ca);
		for(int i = 1; i <= n; i++) {
            printf("%.6lf\n",ans[i] / ans[0]);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值