这道题不能凭感觉做了。要套公式
r个人买了东西叫事件E, 第i个人买东西的概率叫做事件Ei
求得是P(E|Ei), 则P(E|Ei)= P(E|Ei)/ P(E)
那么P(E)可以枚举求得, 用递归求排列,然后把每一种
排列的概率加起来就是总的概率
然后 P(E|Ei)就是要求在排列中当前这个事件会发生
所以可以发现在递归过程中可以同时求P(E|Ei)和P(E)
所以一遍枚举就ok了
Select Code
#include<cstdio>
#include<cstring>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
const int MAXN = 30;
int n, r, buy[MAXN];
double p[MAXN], sum[MAXN];
void dfs(int d, int c, double prob)
{
if(c > r || d - c > n - r) return;
if(d == n)
{
sum[n] += prob;
REP(i, 0, n)
if(buy[i])
sum[i] += prob;
return;
}
buy[d] = 0;
dfs(d + 1, c, prob * (1 - p[d]));
buy[d] = 1;
dfs(d + 1, c + 1, prob * p[d]);
}
int main()
{
int kase = 0;
while(~scanf("%d%d", &n, &r) && n)
{
REP(i, 0, n) scanf("%lf", &p[i]);
memset(sum, 0, sizeof(sum));
dfs(0, 0, 1.0);
printf("Case %d:\n", ++kase);
REP(i, 0, n) printf("%.6lf\n", sum[i] / sum[n]);
}
return 0;
}