贪心,比较明显了(很像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题目都没写报告)