有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 ",P[i]/B); } }