题目连接: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; }