bzoj 2802 贪心+堆

61 篇文章 0 订阅
25 篇文章 0 订阅

题意:每天上午进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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值