简介:
有n个人去逛超市,每个人都有不同的概率买东西
逛完之后,有r个人买了东西,计算每个人买了东西的概率
分析:
“r个人买了东西”这个事件叫E,“第i个人买了东西”这个事件叫Ei
我们要求的是:P(Ei|E)
条件概率:
P(A|B)=P(AB)|P(B)
那么怎么求解P(E)呢:
因为最多只有20个人,我们可以枚举每个人是否买了东西(1为买了,0为没买)
P(E)就是所有情况中,1的个数为r的情况的概率和
计算概率:
例如:11100
P=P1*P2*P3*(1-P4)*(1-P5)
而P(EEi)就是在上述情况中,i的状态是1时的概率和
两部分都可以在一次dfs中统计出来
//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
int a[30],n,r;
double sum[30],tot;
double P[30];
void js()
{
double ans=1.0;
for (int i=1;i<=n;i++)
if (a[i]==1)
ans*=P[i];
else ans*=(1-P[i]);
tot+=ans;
for (int i=1;i<=n;i++)
if (a[i]==1) sum[i]+=ans;
}
void dfs(int t,int z)
{
if (t>n)
{
if (z==0) js();
return;
}
if (n-t+1<z) return; //剪枝
for (int i=0;i<=1;i++)
{
a[t]=i;
if (i==1) dfs(t+1,z-1);
else dfs(t+1,z);
a[t]=0;
}
}
int main()
{
int cnt=0;
while (scanf("%d%d",&n,&r)!=EOF&&n)
{
for (int i=1;i<=n;i++) scanf("%lf",&P[i]);
memset(sum,0,sizeof(sum));
tot=0;
dfs(1,r);
printf("Case %d:\n",++cnt);
for (int i=1;i<=n;i++)
printf("%.6lf\n",sum[i]/tot);
}
return 0;
}