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