5461. 【NOIP2017提高A组冲刺11.8】购物

Description

 X 城的商场中,有着琳琅满目的各种商品。一日,小X 带着小Y 前来购物,小Y 一共看中了n件商品,每一件商品价格为Pi。

小X 现在手中共有m个单位的现金,以及k 张优惠券。

小X 可以在购买某件商品时,使用至多一张优惠券,若如此做,该商品的价格会下降至Qi。

小X 希望尽可能多地满足小Y 的愿望,所以小X 想要知道他至多能购买多少件商品。

 

Input

第一行包含三个整数n,k,m,表示商品总数,小X 拥有的优惠券与现金总数。

接下来n行每行包含两个整数Pi,Qi。

 

Output

 共一行包含一个整数,表示小X 至多能购买的物品数。

Solutions

首先,K 张优惠券或是全部用上,或是购买的物品不足 K 个,且所有的物品都用上了优惠券。不妨先购买 Qi 最小的 K 件物品,

然后将这些商品的 (Pi - Qi) 记录在小根堆中,视为能够花费 Pi - Qi 重新获得一张优惠券,以此为根据,贪心即可。

本题c++选手优势题,然而关我什么事。

代码

(巨丑无比)

  1 var
  2   m,ans:int64;
  3   n,k,tot1,tot2,tot,num:longint;
  4   a,b:array [0..50001] of longint;
  5   p,q:array [0..50001,1..2] of longint;
  6 
  7 procedure down1(i:longint);
  8 var
  9   j:longint;
 10   t:array [1..2] of longint;
 11 begin
 12   while i<=tot1 shr 1 do
 13     begin
 14       j:=2*i;
 15       if (j<tot1) and (p[j+1,1]<p[j,1]) then
 16         inc(j);
 17       if p[i,1]>p[j,1] then
 18         begin
 19           t:=p[i]; p[i]:=p[j]; p[j]:=t;
 20           i:=j;
 21         end else break;
 22     end;
 23 end;
 24 
 25 procedure up1(i:longint);
 26 var
 27   j:longint;
 28   t:array [1..2] of longint;
 29 begin
 30   j:=i;
 31   while (j>1) and (p[j,1]<p[j shr 1,1]) do
 32     begin
 33       t:=p[j]; p[j]:=p[j shr 1]; p[j shr 1]:=t;
 34       j:=j shr 1;
 35     end;
 36 end;
 37 
 38 procedure down2(i:longint);
 39 var
 40   j:longint;
 41   t:array [1..2] of longint;
 42 begin
 43   while i<=tot2 shr 1 do
 44     begin
 45       j:=2*i;
 46       if (j<tot2) and (q[j+1,1]<q[j,1]) then
 47         inc(j);
 48       if q[i,1]>q[j,1] then
 49         begin
 50           t:=q[i]; q[i]:=q[j]; q[j]:=t;
 51           i:=j;
 52         end else break;
 53     end;
 54 end;
 55 
 56 procedure up2(i:longint);
 57 var
 58   j:longint;
 59   t:array [1..2] of longint;
 60 begin
 61   j:=i;
 62   while (j>1) and (q[j,1]<q[j shr 1,1]) do
 63     begin
 64       t:=q[j]; q[j]:=q[j shr 1]; q[j shr 1]:=t;
 65       j:=j shr 1;
 66     end;
 67 end;
 68 
 69 procedure down(i:longint);
 70 var
 71   j,t:longint;
 72 begin
 73   while i<=tot shr 1 do
 74     begin
 75       j:=2*i;
 76       if (j<tot) and (a[j+1]<a[j]) then
 77         inc(j);
 78       if a[i]>a[j] then
 79         begin
 80           t:=a[i]; a[i]:=a[j]; a[j]:=t;
 81           i:=j;
 82         end else break;
 83     end;
 84 end;
 85 
 86 procedure up(i:longint);
 87 var
 88   j,t:longint;
 89 begin
 90   j:=i;
 91   while (j>1) and (a[j]<a[j shr 1]) do
 92     begin
 93       t:=a[j]; a[j]:=a[j shr 1]; a[j shr 1]:=t;
 94       j:=j shr 1;
 95     end;
 96 end;
 97 
 98 procedure init;
 99 var
100   i:longint;
101 begin
102   readln(n,k,m);
103   tot1:=n; tot2:=n;
104   for i:=1 to n do
105     begin
106       readln(p[i,1],q[i,1]);
107       b[i]:=p[i,1];
108       q[i,2]:=i; up2(i);
109       p[i,2]:=i; up1(i);
110     end;
111 end;
112 
113 procedure main;
114 var
115   i:longint;
116 begin
117   tot:=k; ans:=0; num:=0;
118   for i:=1 to k do
119     if ans+q[1,1]<=m then
120       begin
121         ans:=ans+q[1,1]; inc(num);
122         a[i]:=b[q[1,2]]-q[1,1];
123         b[q[1,2]]:=-1;
124         q[1]:=q[tot2]; dec(tot2); down2(1);
125         up(i);
126       end;
127   if num<k then
128     begin
129       writeln(num);
130       exit;
131     end;
132   while (ans<=m) do
133     begin
134       while b[p[1,2]]=-1 do
135         begin
136           p[1]:=p[tot1]; dec(tot1); down1(1);
137         end;
138       while b[q[1,2]]=-1 do
139         begin
140           q[1]:=q[tot2]; dec(tot2); down2(1);
141         end;
142       if p[1,1]<q[1,1]+a[1] then
143         begin
144           ans:=ans+p[1,1];
145           b[p[1,2]]:=-1;
146           if b[q[1,2]]=-1 then
147             begin
148               dec(tot2); down2(1);
149             end;
150           p[1]:=p[tot1]; dec(tot1); down1(1);
151         end else
152         begin
153           ans:=ans+q[1,1]+a[1];
154           a[1]:=a[tot]; dec(tot); down(1);
155           inc(tot);
156           a[tot]:=b[q[1,2]]-q[1,1];
157           b[q[1,2]]:=-1;
158           up(tot);
159           q[1]:=q[tot2]; dec(tot2); down2(1);
160         end;
161       inc(num);
162       if (num=n) and (ans<=m) then
163         begin
164           num:=num+1;
165           break;
166         end;
167     end;
168   writeln(num-1);
169 end;
170 
171 begin
172   assign(input,'shopping.in');
173   assign(output,'shopping.out');
174   reset(input);
175   rewrite(output);
176   init;
177   main;
178   close(input);
179   close(output);
180 end.
原文地址:https://www.cnblogs.com/zyx-crying/p/9437927.html