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.