poj之旅——2976

思路:依然需要确定一个贪心策略,每次贪心地去掉那些对正确率贡献小的考试。如何确定某个考试[a_i, b_i]对总体准确率x的贡献呢?a_i / b_i肯定是不行的,不然例子里的[0,1]会首当其冲被刷掉。在当前准确率为x的情况下,这场考试“额外”对的题目数量是a_i – x * b_i,当然这个值有正有负,恰好可以作为“贡献度”的测量。于是利用这个给考试排个降序,后k个刷掉就行了。

程序:(切不可直接复制)

var
  n,k,i,l,r,mid:longint;
  a,b:array[0..110000]of longint;
procedure qsort(x,l,r:longint);
var
  mm,i,j,xx,t:longint;
begin
  i:=l;j:=r;mm:=(l+r)shr 1;
  xx:=a[mm]-x*b[mm];
  repeat
    while a[i]-x*b[i]>xx do i:=i+1;
    while a[j]-x*b[j]<xx do j:=j-1;
    if i<=j then
     begin
       t:=a[i];a[i]:=a[j];a[j]:=t;
       t:=b[i];b[i]:=b[j];b[j]:=t;
       i:=i+1;j:=j-1;
     end;
  until i>j;
  if i<r then qsort(x,i,r);
  if j>l then qsort(x,l,j);
end;
function check(x:longint):boolean;
var
  sa,sb,i:longint;
begin
  qsort(x,1,n);
  sa:=0;sb:=0;
  for i:=1 to n-k do
   begin
     sa:=sa+a[i];sb:=sb+b[i];
   end;
  exit(sa/sb>x);
end;
begin
  readln(n,k);
  while (n+k>0) do
   begin
     for i:=1 to n do begin read(a[i]);a[i]:=a[i]*100000;end;
     for i:=1 to n do read(b[i]);
     l:=0;r:=100000;
     while l<=r do
      begin
        mid:=(l+r)shr 1;
        if check(mid) then l:=mid+1
         else r:=mid-1;
      end;
     writeln(round(l/1000));
     readln(n,k);
   end;
end.

你可能感兴趣的:(poj之旅——2976)