贪心,比较明显了(很像USACO的风格);

按时间限制排序(升序)

顺次处理,如果当前时间能够修复就修复

否则就在之前修复的任务中找一个耗时最多(大于当前任务)的,改成修当前任务;

显然这样最优吧,

毫无疑问要维护大根堆(耗时);

code

var heap,a,w:array[0..150010] of longint;

    ans,i,t,j,n,now,x,y:longint;

procedure swap(var a,b:longint);

  var c:longint;

  begin

    c:=a;

    a:=b;

    b:=c;

  end;

procedure sift(i:longint);

  var j:longint;

  begin

    j:=i shl 1;

    while j<=t do

    begin

      if (j+1<=t) and (heap[j]<heap[j+1]) then inc(j);

      if heap[i]<heap[j] then

      begin

        swap(heap[i],heap[j]);

        i:=j;

        j:=j shl 1;

      end

      else break;

    end;

  end;


procedure up(i:longint);

  var j:longint;

  begin

    j:=i shr 1;

    while j>0 do

    begin

      if heap[i]>heap[j] then

      begin

        swap(heap[i],heap[j]);

        i:=j;

        j:=i shr 1;

      end

      else break;

    end;

  end;


procedure sort(l,r: longint);

  var i,j,x,y: longint;

  begin

    i:=l;

    j:=r;

    x:=a[(l+r) div 2];

    repeat

      while a[i]<x do inc(i);

      while x<a[j] do dec(j);

      if not(i>j) then

      begin

        swap(a[i],a[j]);

        swap(w[i],w[j]);

        inc(i);

        dec(j);

      end;

    until i>j;

    if l<j then sort(l,j);

    if i<r then sort(i,r);

  end;


begin

  readln(t);

  for i:=1 to t do

  begin

    readln(x,y);

    if y>=x then

    begin

      inc(n);

      w[n]:=x;

      a[n]:=y;

    end;

  end;

  sort(1,n);

  now:=0;

  t:=0;

  for i:=1 to n do

    if now+w[i]<=a[i] then

    begin

      inc(ans);

      now:=now+w[i];

      inc(t);

      heap[t]:=w[i];

      up(t);

    end

    else if w[i]<heap[1] then

    begin

      now:=now-heap[1]+w[i];

      heap[1]:=w[i];

      sift(1);

    end;

  writeln(ans);

end.

今天解题报告就补到这里吧(好多bzoj题目都没写报告)

posted on 2014-04-08 22:07  acphile  阅读(137)  评论(0编辑  收藏  举报