5461. 【NOIP2017提高A组冲刺11.8】购物
(File IO): input:shopping.in output:shopping.out
Time Limits:
1000 ms Memory Limits: 524288 KB Detailed Limits
Goto ProblemSet
Description
X 城的商场中,有着琳琅满目的各种商品。一日,小X 带着小Y 前来购物,小Y 一共看中了n件商品,每一件商品价格为Pi。小X 现在手中共有m个单位的现金,以及k 张优惠券。小X 可以在购买某件商品时,使用至多一张优惠券,若如此做,该商品的价格会下降至Qi。
小X 希望尽可能多地满足小Y 的愿望,所以小X 想要知道他至多能购买多少件商品。
小X 希望尽可能多地满足小Y 的愿望,所以小X 想要知道他至多能购买多少件商品。
Input
第一行包含三个整数n,k,m,表示商品总数,小X 拥有的优惠券与现金总数。
接下来n行每行包含两个整数Pi,Qi。
接下来n行每行包含两个整数Pi,Qi。
Output
共一行包含一个整数,表示小X 至多能购买的物品数。
Sample Input
4 1 7 3 2 2 2 8 1 4 3
Sample Output
3 样例解释:一种最优的购买方式是购买1,2,3号物品,并用优惠券购买物品3,总共花费为3+2+1=6。
做法:对Qi 和 Pi 排序, 先最小的K个Qi,然后将这K个Pi - Qi放进一个小根堆,每次比较Pi 和 Qi + 小根堆堆顶的值,更新答案和小根堆。一种具有撤销操作的贪心。
代码如下:
View Code


1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <queue> 5 #include <algorithm> 6 #define LL long long 7 #define N 50007 8 using namespace std; 9 LL n, m, k, p[N], tot; 10 struct arr 11 { 12 LL pi, qi; 13 }q[N]; 14 priority_queue < LL, vector<LL>, greater<LL> > Q; 15 16 LL cmp(arr x, arr y) 17 { 18 return x.qi < y.qi; 19 } 20 21 int main() 22 { 23 freopen("shopping.in", "r", stdin); 24 freopen("shopping.out", "w", stdout); 25 scanf("%lld%lld%lld", &n, &k, &m); 26 for (int i = 1; i <= n; i++) 27 scanf("%lld%lld", &q[i].pi, &q[i].qi); 28 sort(q + 1, q + n + 1, cmp); 29 LL ans = 0, site = 0; 30 for (int i = 1; i <= k; i++) 31 { 32 if (m - q[i].qi >= 0) 33 { 34 m -= q[i].qi; 35 ans++; 36 Q.push(q[i].pi - q[i].qi); 37 site = i; 38 } 39 else break; 40 } 41 if (site < k) 42 { 43 printf("%lld", ans); 44 return 0; 45 } 46 for (int i = site + 1; i <= n; i++) 47 p[i - site] = q[i].pi; 48 tot = n - site; 49 sort(p + 1, p + n - site + 1); 50 LL j = 1; 51 site++; 52 while (m >= 0 && (j <= tot || site <= n)) 53 { 54 LL now = Q.top(); 55 LL mi = min(p[j], q[site].qi + now); 56 if (m - mi >= 0) 57 { 58 if (mi == p[j]) 59 { 60 m -= p[j]; 61 j++; 62 ans++; 63 if (j > tot) p[j] = 0x7f7f7f7f; 64 if (ans == n) break; 65 } 66 else 67 { 68 m -= q[site].qi + now; 69 ans++; 70 Q.pop(); 71 Q.push(q[site].pi - q[site].qi); 72 site++; 73 } 74 } 75 else break; 76 } 77 printf("%lld", ans); 78 }