【搜索 数学 概率】JZOJ_2941 贿赂

本文探讨了一种算法,用于解决在有限糖果资源下,如何通过贿赂议员来最大化议案通过的概率问题。考虑到议员的级别和忠诚度,以及议案通过的特殊条件,文章提供了一个包含暴力分配糖果和求概率的C++代码实现。

题意

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);
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值