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的倍数
题解
首先,这题是到非常简单的概率题。
我们发现由于数据极小,所以我们考虑直接暴力。
先
O
(
9
!
)
O(9!)
O(9!)地弄出k如何分配。
然后再
O
(
2
n
)
O(2^n)
O(2n)地弄出投反对票的情况。
然后,如果支持超过一半,则直接把支持的概率加入答案,
否则就杀人。
最后把当前答案与最终答案判断大小即可。
标程
{$inline on}
var
i,j,k,l,n,m:longint;
x,y,z:array[0..18] of extended;
bz:array[0..18] of boolean;
sum:array[1..18] of longint;
answer,jl,a,ans:extended;
function max(x,y:extended):extended; inline;
begin
if x>y then exit(x);exit(y);
end;
function min(x,y:longint):longint; inline;
begin
if x<y then exit(x);exit(y);
end;
procedure dg(dep,gs:longint;level:extended);
var
i,j,k:Longint;
op,p,q:extended;
begin
if dep=n then
begin
if gs>(n) div 2 then
begin
op:=1;
for i:=1 to n do
begin
op:=op*z[i]/100;
end;
ans:=ans+op;
end
else
begin
p:=a+level;
q:=a;
op:=0;
op:=op+q/p;
for i:=1 to n do
begin
op:=op*z[i]/100;
end;
ans:=ans+op;
end;
end
else
begin
z[dep+1]:=100-y[dep+1];
bz[dep+1]:=false;
if z[dep+1]<>0 then
dg(dep+1,gs,level+x[dep+1]);
z[dep+1]:=y[dep+1];
bz[dep+1]:=true;
if z[dep+1]<>0 then
dg(dep+1,gs+1,level);
end;
end;
procedure dfs(dep,k:longint);
var
i,j:longint;
begin
if k=0 then
begin
for i:=1 to 9 do bz[i]:=false;
ans:=0;
z[1]:=100-y[1];
bz[1]:=false;
dg(1,0,x[1]);
z[1]:=y[1];
bz[1]:=true;
dg(1,1,0);
answer:=max(ans,answer);
end
else
begin
for i:=0 to min(k,trunc((100-y[dep])/10)) do
begin
y[dep]:=y[dep]+i*10;
if k-i<=sum[dep+1] then
begin
dfs(dep+1,k-i);
end;
y[dep]:=y[dep]-i*10;
end;
end;
end;
begin
//assign(input,'0data.in');reset(input);
readln(n,m,a);
answer:=0;
for i:=1 to n do
begin
readln(x[i],y[i]);
end;
for i:=n downto 1 do
begin
sum[i]:=sum[i+1]+trunc((100-y[i])/10);
end;
dfs(1,m);
writeln(answer:0:6);
end.
end.