根据贝叶斯公式:(百度百科) ,即条件概率的一个推广。 我们需要求出每个人在B这个前提条件下的概率,再除以tot(r个人买东西的概率) 即可得到答案。一开始用递归穷举,结果超时,后来发现,原来我是老老实实的枚举了一遍,但是这个过程中可能存在大量的重复现象。正确的策略是只枚举当前人之后的人。还有一点需要注意的是当n = 1,r = 0 ,P = 1.0 这个数据是不存在的。 因为这时会发生除0错误。所以下面代码中有一些是不必要的。
#include<bits/stdc++.h>
using namespace std;
int n,r,A[25];
double p[25],sum[25],tot;
void dfs(int k ,int cur) {
if(cur==r) {
double cur_p=1;
for(int i=1;i<=n;++i){
if(!A[i]) cur_p*=(1-p[i]);
else cur_p*=p[i];
} tot+=cur_p;
for(int i=1;i<=n;++i)
if(A[i]==1) sum[i]+=cur_p;
}
else for(int i=k;i<=n;++i) {
if(!A[i]) {
A[i]=1;
dfs(i+1,cur+1);
A[i]=0;
}
}
}
int main() {
int maxn = 0;
while(scanf("%d%d",&n,&r)!=EOF) {
if(n==0&&r==0) return 0;
for(int i=1;i<=n;i++) scanf("%lf",&p[i]);
memset(A,0,sizeof(A));
memset(sum,0,sizeof(sum));
printf("Case %d:\n",++maxn);
tot = 0;
dfs(1,0);
if(tot==0) for(int i=1;i<=n;i++) //这个部分是不需要的。
printf("%.6lf\n",0.0);
else for(int i=1;i<=n;i++)
printf("%.6lf\n",sum[i]/tot);
}
return 0;
}