题意:每天上午进ai的货物,中午有顾客买bi个,我们可以满足他可以无视他,但若要满足顾客要求必须有足够的库存,问最多能满足多少顾客要求
这个贪心很经典...,来的顾客是有时间顺序的,一个一个按顺序处理不需要排序(与bzoj1029 不同)
原则:能多则多(能卖则卖),对于卖不了的,我们以让库存越多越好,即去我们卖的人里面找到卖的最多的,判断二者大小,如果这个人买的少就替换,卖个这个人而不卖给那个买的多的人
我们用一个大根堆来维护我们已经卖了的情况,令now表示库存
(1)如果我们可以卖给第i个人,即 b[i]<=now ,直接入堆,now-=b[i]
(2)如果我们卖不了第i个人,即 b[i]>now ,那么我们判断b[i] 与 我们维护的大根堆堆顶元素 的大小,
如果 b[i]<heap[1] ,就用b[i]替换heap[1],维护一下大根堆,并更新now;否则无操作
type
rec=record
key,day:longint;
end;
var
n,x,size,t :longint;
now :int64;
i :longint;
flag :array[0..250010] of boolean;
a :array[0..250010] of longint;
heap :array[0..250010] of rec;
procedure swap(var a,b:rec);
var
c:rec;
begin
c:=a; a:=b; b:=c;
end;
procedure heap_up(i:longint);
begin
if i=1 then exit;
while (i>1) do
begin
if (heap[i].key>heap[i div 2].key) or ((heap[i].key=heap[i div 2].key) and (heap[i].day>heap[i div 2].day)) then
begin
swap(heap[i],heap[i div 2]);
i:=i div 2;
end else break;
end;
end;
procedure heap_down(i:longint);
var
t:longint;
begin
while (i*2<=size) do
begin
if (heap[i*2].key>heap[i].key) or ((heap[i].key=heap[i div 2].key) and (heap[i].day>heap[i div 2].day)) then t:=i*2 else t:=i;
if (i*2+1<=size) then
if (heap[i*2+1].key>heap[t].key) or ((heap[i].key=heap[i div 2].key) and (heap[i].day>heap[i div 2].day)) then t:=i*2+1;
if (i<>t) then
begin
swap(heap[i],heap[t]);
i:=t;
end else break;
end;
end;
begin
read(n);
for i:=1 to n do read(a[i]);
now:=0;size:=0;t:=0;
for i:=1 to n do
begin
now:=now+a[i];
read(x);
if (x<=now) then
begin
inc(size);
heap[size].key:=x;
heap[size].day:=i;
heap_up(size);
dec(now,x);
flag[i]:=true;
end else
if (x<heap[1].key) then
begin
inc(now,heap[1].key);
dec(now,x);
flag[heap[1].day]:=false;
flag[i]:=true;
heap[1].key:=x;
heap[1].day:=i;
heap_down(1);
end;
end;
writeln(size);
for i:=1 to n do
if flag[i] then write(i,' ');writeln;
end.
—— by Eirlys