设事件B为一共有r个人买了东西,设事件Ai为第i个人买了东西。
那么这个题目实际上就是求P(Ai|B),而P(Ai|B)=P(AiB)/P(B),其中P(AiB)表示事件Ai与事件B同时发生的概率,同时总状态并不多,因此我们可以枚举买东西的状态预处理出P(AiB)和P(B),再代入计算即可。
枚举就是一般的dfs,关键是明白这个过程.
1 #include <cstdio> 2 #include <cstring> 3 int n,r; 4 double p[25],b[25],sum; //sum是从n个人选出r个人的总的概率 即 P(B) 5 bool vis[25]; //b[i]代表在选出r个人的前提下选中i的概率 6 7 void dfs(int k,int d) 8 { 9 if(d==r) 10 { 11 double pp=1.0; 12 for(int j=0;j<n;j++) 13 if(vis[j]) pp*=p[j]; 14 else pp*=(1.0-p[j]); 15 for(int j=0;j<n;j++) 16 if(vis[j]) b[j]+=pp; 17 sum+=pp; 18 } 19 else 20 { 21 for(int i=k+1;i<n;i++) 22 { 23 vis[i]=1; 24 dfs(i,d+1); 25 vis[i]=0; 26 } 27 } 28 } 29 int main() 30 { 31 int cas=0; 32 while(~scanf("%d%d",&n,&r)&&n) 33 { 34 sum=0.0; 35 memset(vis,0,sizeof(vis)); 36 memset(b,0,sizeof(b)); 37 for(int i=0;i<n;i++) scanf("%lf",&p[i]); 38 dfs(-1,0); 39 printf("Case %d: ",++cas); 40 for(int i=0;i<n;i++) 41 printf("%.6lf ",b[i]/sum); 42 } 43 return 0; 44 }