jzoj2941. 贿赂

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!)地弄出k如何分配。
然后再O(2n)O(2^n)地弄出投反对票的情况。
然后,如果支持超过一半,则直接把支持的概率加入答案,
否则就杀人。
最后把当前答案与最终答案判断大小即可。

标程

{$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.


原文地址:https://www.cnblogs.com/RainbowCrown/p/11148369.html