题意
有NNN个议员,给出他们的级别和忠诚度。
我们手上有KKK个糖果,每使用一个可以使一位议员增加10点忠诚度。
我们现在有一个议案,当议员同意个数严格大于人数的一半时才能算通过。否则你要把所有投反对票的人杀死,成功率为A/(A+B)A/(A+B)A/(A+B),其中AAA为给定的参数,BBB为所有投反对票的议员的级别总和。
求出在最优贿赂方案的情况下议案通过的概率。
思路
暴力分配糖果,然后暴力求概率。
代码
#include<cstdio>
#include<algorithm>
int n, k, A;
int a[10];
double b[10];
double ans, t;
void check(int dep, int num, int s, double k) {//其中num为赞同的人数,s为反对级别总和,k为该情况的概率
if (!k) return;
if (dep > n) {
if (num > n / 2) t += k;
else t += k * (double)A / (A + s);
return;
}
check(dep + 1, num + 1, s, k * b[dep]);//赞同
check(dep + 1, num, s + a[dep], k * (1 - b[dep]));//反对
}
void dfs(int rest, int dep) {//分配糖果
if (!rest) {
t = 0;
check(1, 0, 0, 1);
ans = std::max(ans, t);
return;
}
if (dep > n) return;
for (int i = 0; i <= rest; i++) {
if (b[dep] + (double)i / 10 > 1.000001) break;
b[dep] += (double)i / 10;
dfs(rest - i, dep + 1);
b[dep] -= (double)i / 10;
}
}
int main() {
scanf("%d %d %d", &n, &k, &A);
for (int i = 1; i <= n; i++) {
scanf("%d %lf", &a[i], &b[i]);
b[i] /= 100;
}
dfs(k, 1);
printf("%.6lf", ans);
}
本文探讨了一种算法,用于解决在有限糖果资源下,如何通过贿赂议员来最大化议案通过的概率问题。考虑到议员的级别和忠诚度,以及议案通过的特殊条件,文章提供了一个包含暴力分配糖果和求概率的C++代码实现。
1527

被折叠的 条评论
为什么被折叠?



