UVa11181 条件概率(紫书327页)

来源:互联网 发布:微信是什么软件 编辑:程序博客网 时间:2024/06/16 13:39

时间限制:1秒 内存限制:64M
【问题描述】

  有n个人准备去超市逛,其中第i个人买东西的概率是Pi,逛完以后你得知有r个人买了东西。根据这一信息,请计算每个人实际买了东西的概率。输入 n 和 r,输出每个人实际买了东西的概率。

【输入格式】

  包含多组数据,每组数据第一行为n,r,接下来的n行,第i行为Pi,他们的意义如题目描述。输入的最后以行为0 0,表示输入结束。

【输出格式】

  每组数据开始输出Case k(k表示测试数据组数),接下的n行,第i行表示第i个人实际买了东西的概率。

【输入样例】

3 2
0.10
0.20
0.30
5 1
0.10
0.10
0.10
0.10
0.10
0 0

【输出样例】

Case 1:
0.413043
0.739130
0.847826
Case 2:
0.200000
0.200000
0.200000
0.200000
0.200000

【数据范围】

1<=n<=20
0<=r<=n

【来源】

UVa11181条件概率(紫书327页)

一道条件概率的题:条件概率公式:P(A|B)=P(AUB)/P(B)

简单来说,A在B发生的前提下发生的概率为2个都发生的概率除以B发生的概率。

所以这道题就是每个点发生的概率除以tot(m个人买的概率,不论是哪m个人)的值了。

枚举每个人买不买,把每种情况的概率记录下来,如果刚好m个人买了,那就让tot加这个值,然后这种情况每个买了的人的概率加这个值。

详细代码如下:

#include<cstdlib>#include<cstdio>#include<cstring>#include<iostream>using namespace std;int n,m;double a[25],ans[25]={0},tot=0;bool vis[25];void run(int i,int b,double t){    if(i>n)    {        if(b==m)        {            tot+=t;            for(int i=1;i<=n;i++)if(vis[i])            ans[i]+=t;        }        return;    }    vis[i]=1;    run(i+1,b+1,t*a[i]);    vis[i]=0;    run(i+1,b,t*(1-a[i]));}int main(){    //freopen("in.txt","r",stdin);    scanf("%d%d",&n,&m);    int T=0;    while(n!=0)    {        printf("Case %d:\n",++T);        for(int i=1;i<=n;i++)         scanf("%lf",&a[i]);        memset(vis,0,sizeof(vis));        memset(ans,0,sizeof(ans));        tot=0;        run(1,0,1);        for(int i=1;i<=n;i++)         printf("%.6lf\n",ans[i]/tot);        scanf("%d%d",&n,&m);    }       return 0;}
1 0