UVA 11181 Probability|Given

Probability|Given

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

 

思路:

事件A:n个人中有r个人买东西

事件B:第i个人买东西

在事件A的前提下事件B发生的概率=P(B)/P(A)

P(A):

假设有3个人

那所有的可能情况为 000  001  010  011 100 101 110 111

有2个人买东西:011  101  110

那么P(A)= (1-p[1])*p[2]*p[3]  +  p[1]*(1-p[2])*p[3]  +  p[1]*p[2]*(1-p[3])

P(B):

假设第1个人

011  101  110  只有  101  110 符合要求

P(B)= p[1]*(1-p[2])*p[3]  +  p[1]*p[2]*(1-p[3])

综上,第1个人买东西的概率= P(B)/P(A)

错因:搜索的姿势不对。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 21
using namespace std;
int n,m,nm;
bool vis[MAXN];
double B,A[MAXN],Cu[MAXN],P[MAXN];
void dfs(int now,int tot,double num){
    if(tot==m){
        for(int i=1;i<=n;i++)
            if(!vis[i])    num*=Cu[i];
        for(int i=1;i<=n;i++)
            if(vis[i])    P[i]+=num;
        B+=num;
        return ;
    }
    for(int i=now+1;i<=n;i++){
        vis[i]=1;
        dfs(i,tot+1,num*A[i]);
        vis[i]=0;
    }        
} 
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        B=0;
        memset(A,0,sizeof(A));
        memset(P,0,sizeof(P));
        memset(Cu,0,sizeof(Cu));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){
            scanf("%lf",&A[i]);
            Cu[i]=1-A[i];
        }
        dfs(0,0,1);
        cout<<"Case "<<++nm<<":"<<endl; 
        for(int i=1;i<=n;i++)
            printf("%.6lf\n",P[i]/B);
    }
    
}

 

posted @ 2017-09-28 11:34  一蓑烟雨任生平  阅读(133)  评论(0编辑  收藏  举报