codeforce 810B Summer sell-off (贪心 排序)
题意:
商店准备用n天售货(每天的货物都是一样的),第i天会卖ki件货物,并且会有li个顾客来买。
如果货物没卖完, 那么每个顾客一定会买一件。 如果货物有剩, 不会保存到第二天。
现在给定一个f, 说明f天商店会双倍进货, 求哪几天选为f天商店售货最多。
第一个用例选第二第四天加倍, 第二个用例选第三天加倍。
分析:
一开始想了一个错误的贪心,以为只要求出min(货物*2,顾客)的值, 然后根据这个值来排序, 前f个取min(货物*2,顾客),后面的取min(货物,顾客)就能得出正确答案。
但考虑一个问题:
如果顾客<=商品数目, 那么将货物加倍,其实跟原来能卖的是一样的(都是=顾客数目),等同于浪费了一个加倍机会, 所以不如把这个加倍的机会留给 顾客 > 商品 的天数。
所以要先求出每一天加倍和不加倍的差值, 然后根据这个差值排序, 前f天加上这个差值, 后面的取min(货物,顾客),就能得出正确答案。
1 #include<bits/stdc++.h>
2 using namespace std;
3 struct B
4 {
5 long long goods;
6 long long cus;
7 long long can_earn;
8 };
9 B day[100005];
10 bool cmp(const B& x, const B &y)
11 {
12 return x.can_earn > y.can_earn;
13 }
14 int main()
15 {
16 int n, f;
17 scanf("%d %d", &n, &f);
18 long long ans = 0;
19 for(int i = 0; i < n; i++)
20 {
21 scanf("%lld %lld", &day[i].goods, &day[i].cus);
22 day[i].can_earn = min(day[i].goods*2,day[i].cus) - min(day[i].goods,day[i].cus);
23
24 }
25 sort(day,day+n,cmp);
26
27 for(int i = 0; i < n; i++)
28 {
29 if(f)
30 {
31 f--;
32 ans += day[i].can_earn;
33 }
34 ans += min(day[i].goods,day[i].cus);
35 }
36 printf("%lld\n", ans);
37 }