紫书 例题 10-11 UVa 11181(概率计算)

这道题不能凭感觉做了。要套公式

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;
}

猜你喜欢

转载自blog.csdn.net/qq_34416123/article/details/81065333