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 }

 

posted @ 2017-05-24 15:32  Neord  阅读(342)  评论(0编辑  收藏  举报