【JZOJ A组】贿赂

Description

议会里有N个议员,每个议员有两个属性:级别和忠诚值。

现在你要在议会通过一个议案,一个议案通过当且仅当严格超过一半的议员投赞同票。一个议员投赞同票的几率就是忠诚值除以100。

议员们有着奇怪的癖好:他们都喜欢吃糖。你带了K个糖果用来贿赂议员,每个糖果的作用是使得某个议员的忠诚值增加10。贿赂要在投票开始前完成。(注意任意议员的忠诚值不可能大于100)

投票之后,如果议案没有通过,你就会很暴力地把投了反对票的所有议员暗杀掉。假设你要暗杀的议员集合是S,那么成功率就是A/(A+B);其中A是给定的常数,B是S中所有议员级别的和。当暗杀成功后你的议案就会获得通过。

现在要求最优贿赂方案下最大的成功几率是多大。

Input

第一行三个整数N,K和A,意义如题目所述;

接下来N行每行两个整数ai,bi分别表示每个议员的级别和忠诚值。

Output

一个实数表示可能的最大成功几率。保留6位小数。

Sample Input

5 3 100
11 80
14 90
23 70
80 30
153 70

Sample Output

0.962844

Data Constraint

对于40%的数据,保证N,K≤5

对于100%的数据,保证N,K≤9,A,ai≤9999,bi是10的倍数

思路

这题暴力能过!!!

首先枚举这些糖贿赂谁,然后再算出这种贿赂方式的成功率,取最大值即可

代码

#include
#include
#include
#define db double
using namespace std;
double ans=0;
int n,k,p,a[20],b[20];
db solve(int x,int agree,int sum)
{
	db s;
	if(x>n)
	{
		if(2*agree>n)return 1.0;
		else return (db)p/(db)(p+sum);
	}
	s=(db)b[x]/100*solve(x+1,agree+1,sum)+(db)(1-((db)b[x]/100))*solve(x+1,agree,sum+a[x]);
	return s;
}
void dfs(int dep,int candy)
{
	if(dep==n)
	{
		b[dep]+=candy*10;
		if(b[dep]<=100) ans=max(ans,solve(1,0,0));
		b[dep]-=candy*10;
		return;
	}
	for(int i=0; i<=candy; i++)
	{
		b[dep]+=10*i;
		if(b[dep]<=100) dfs(dep+1,candy-i);
		else
		{
			b[dep]-=10*i; break;
		}
		b[dep]-=10*i;
	}
}
int main()
{
	scanf("%d%d%d",&n,&k,&p);
	for(int i=1; i<=n; i++) scanf("%d%d",&a[i],&b[i]);
	dfs(1,k);
	printf("%.6lf",ans);
}

你可能感兴趣的:(题解)