uva 10417 Gift Exchanging(概率 + dfs)

题目连接:uva 10417 Gift Exchanging


题目大意:有个2B过生日,请了n个朋友,每个朋友都会带一个礼物,礼物都是有包装的,但是包装只有5种,然后现在给出c1 ~c5,表示说现在桌子上出现各种包装的礼物各有多少个,然后告诉你每个人会带来5种包装的概率(和为1),第一个人是2B最好的朋友,2B想随即抽取一个,请问他应该拿哪一种包装的最好,即拿到最好朋友送得礼物的概率最大,输出包装号和概率,有相同概率输出包装号较小的。


解题思路:dfs枚举所有可能情况,并计算出现当前状况的概率为p(A), 然后分别记录最好朋友送某种包装的概率r[i],注意最有的概率p = r[i] / c[i] / p(A).最大即为答案。


#include <stdio.h>
#include <string.h>
#include <math.h>

const int MAXN = 15;
const int N = 5;

int n, cnt[MAXN];
double r[MAXN], p[MAXN][MAXN];

void init() {
	scanf("%d", &n);
	memset(r, 0, sizeof(r));
	for (int i = 0; i < N; i++)
		scanf("%d", &cnt[i]);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < N; j++)
			scanf("%lf", &p[i][j]);
}

double dfs(int d, double c) {
	if (n == d) {
		return c;
	}

	double ans = 0;
	for (int i = 0; i < N; i++) {
		if (cnt[i] && fabs(p[d][i]) > 1e-9) {
			cnt[i]--;

			double t = dfs(d + 1, c * p[d][i]);
			ans += t;

			if (d == 0) r[i] += t;

			cnt[i]++;
		}
	}
	return ans;
}

void solve(double s) {
	int id = 0;
	double ans = 0;
	for (int i = 0; i < N; i++) {
		double c = r[i] / cnt[i];
		if (c - ans > 1e-9) {
			id = i;
			ans = c;
		}
	}
	printf("%d %.3lf\n", id + 1, ans / s);
}

int main () {
	int cas;
	scanf("%d", &cas);
	while (cas--) {
		init();
		double s = dfs(0, 1);
		solve(s);
	}
	return 0;
}


你可能感兴趣的:(uva 10417 Gift Exchanging(概率 + dfs))