JZOJ_100029. 【NOIP2017提高A组模拟7.8】陪审团 (Standard IO)

Description

陪审团制度历来是司法研究中的一个热议话题,由于陪审团的成员组成会对案件最终的结果产生巨大的影响,诉讼双方往往围绕陪审团由哪些人组成这一议题激烈争夺。 小 W 提出了一个甲乙双方互相制衡的陪审团成员挑选方法:假设共有 n 名候选陪审团成员,则由甲先提名 s 位候选人,再由乙在甲提名的 s 位候选人中选出 t 名,作为最终的陪审团成员。显然这里应当有n ≥ s ≥ t。假设候选人 k 对甲、乙的有利程度都可以用一个二元组(𝑥𝑘, 𝑦𝑘)来表示,𝑥𝑘越大说明候选人 k 对甲越有利,𝑦𝑘越大则对乙越有利。在此前提下,双方的目标都变得明确:甲要最大化最终陪审团 t 人的 x 之和,最小化 y之和,乙则反之。 现在甲方决定聘请你为律师,并且事先得知了乙方律师的策略:乙方律师会在你提名的 s 名候选人中选出 t 名使得这 t 人的 y 值之和最大,再保证 y 值之和最大的前提下使得 x 值之和尽量小(在对乙方最有利的前提下对甲方最不利)。 现在你应当慎重地提名 s 位候选人使得最终由乙方律师确定的 t 人 x 值和最大,若有多种方案,则应再使被乙方排除掉的 s-t人的 y 值和尽量大,在此基础上最大化 s 人的 x 值 之和,在此基础上最小化 s 人的 y 值 之和。 你的当事人并不关心你提名的具体是哪些人,只要你告诉他你提名的 s 人的 x 值之和 与 y 值之和。
 

Input

第一行包含三个整数 n,s,t。 接下来 n 行,每行两个整数分别表示𝑥𝑘, 𝑦𝑘。
 

Output

共一行两个整数,分别为 x 值之和与 y 值之和。 
 

Solution

若甲方只能选t名,那乙方就别无选择了。那甲方选s名,乙方是否能也别无选择的选t名呢?

是能的!

首先,将yk从小到大排序(第一次),去后(n-s+t)名。

那么甲方在后面无论怎么选t名,乙方也只能选这t名,因为都比前(s-t)名对乙方的贡献大。

因为要使对甲方的贡献最大,那么在将后(n-s+t)名以xk为关键字从大到小排序(第二次),选前t名。

因为还要求(s-t)名对乙方的贡献尽量大,在将出去t名的序列以yk为关键字从大到小排序(第三次)。

只要第三次排序的序列的yk值不比所选的t名的最小的yk值大,就可以选,选完(s-t)个即可。

 

代码

  1 var
  2   ansx,ansy:int64;
  3   n,s,t:longint;
  4   xk,yk,a,b:array [0..100001] of longint;
  5 procedure init;
  6 var
  7   i:longint;
  8 begin
  9   readln(n,s,t);
 10   for i:=1 to n do
 11     readln(xk[i],yk[i]);
 12 end;
 13 
 14 procedure qsort1(l,r:longint);
 15 var
 16   i,j,mid1,mid2,tk:longint;
 17 begin
 18   if l>r then exit;
 19   i:=l; j:=r;
 20   mid1:=yk[(l+r) div 2];
 21   mid2:=xk[(l+r) div 2];
 22   repeat
 23     while (yk[i]<mid1) or (yk[i]=mid1) and (xk[i]>mid2) do inc(i);
 24     while (yk[j]>mid1) or (yk[j]=mid1) and (xk[j]<mid2) do dec(j);
 25     if i<=j then
 26       begin
 27         tk:=xk[i]; xk[i]:=xk[j]; xk[j]:=tk;
 28         tk:=yk[i]; yk[i]:=yk[j]; yk[j]:=tk;
 29         inc(i); dec(j);
 30       end;
 31   until i>j;
 32   qsort1(i,r);
 33   qsort1(l,j);
 34 end;
 35 
 36 procedure qsort2(l,r:longint);
 37 var
 38   i,j,mid1,mid2,tk:longint;
 39 begin
 40   if l>r then exit;
 41   i:=l; j:=r;
 42   mid1:=xk[(l+r) div 2];
 43   mid2:=yk[(l+r) div 2];
 44   repeat
 45     while (xk[i]>mid1) or (xk[i]=mid1) and (yk[i]>mid2) do inc(i);
 46     while (xk[j]<mid1) or (xk[j]=mid1) and (yk[j]<mid2) do dec(j);
 47     if i<=j then
 48       begin
 49         tk:=xk[i]; xk[i]:=xk[j]; xk[j]:=tk;
 50         tk:=yk[i]; yk[i]:=yk[j]; yk[j]:=tk;
 51         inc(i); dec(j);
 52       end;
 53   until i>j;
 54   qsort2(i,r);
 55   qsort2(l,j);
 56 end;
 57 
 58 procedure qsort3(l,r:longint);
 59 var
 60   i,j,mid1,mid2,tk:longint;
 61 begin
 62   if l>r then exit;
 63   i:=l; j:=r;
 64   mid1:=b[(l+r) div 2];
 65   mid2:=a[(l+r) div 2];
 66   repeat
 67     while (b[i]>mid1) or (b[i]=mid1) and (a[i]>mid2) do inc(i);
 68     while (b[j]<mid1) or (b[j]=mid1) and (a[j]<mid2) do dec(j);
 69     if i<=j then
 70       begin
 71         tk:=a[i]; a[i]:=a[j]; a[j]:=tk;
 72         tk:=b[i]; b[i]:=b[j]; b[j]:=tk;
 73         inc(i); dec(j);
 74       end;
 75   until i>j;
 76   qsort3(i,r);
 77   qsort3(l,j);
 78 end;
 79 
 80 procedure main;
 81 var
 82   i,num,min,tk:longint;
 83 begin
 84   ansx:=0; ansy:=0; num:=0;
 85   qsort1(1,n);
 86   for i:=1 to s-t do
 87     begin
 88       inc(num);
 89       a[num]:=xk[i]; b[num]:=yk[i];
 90     end;
 91   qsort2(s-t+1,n);
 92   min:=maxlongint;
 93   for i:=s-t+1 to s do
 94     begin
 95       ansx:=ansx+xk[i];
 96       ansy:=ansy+yk[i];
 97       if yk[i]<min then min:=yk[i];
 98     end;
 99   for i:=s+1 to n do
100     begin
101       inc(num);
102       a[num]:=xk[i]; b[num]:=yk[i];
103     end;
104   qsort3(1,num);
105   tk:=0;
106   for i:=1 to num do
107     if b[i]<=min then
108       begin
109         inc(tk);
110         ansx:=ansx+a[i];
111         ansy:=ansy+b[i];
112         if tk=s-t then break;
113       end;
114   writeln(ansx,' ',ansy);
115 end;
116 
117 begin
118   init;
119   main;
120 end.

 

posted @ 2018-08-17 15:09  猪都哭了  阅读(252)  评论(0编辑  收藏  举报