POJ3614 Sunscreen(贪心)

题目链接

这道题是对贪心以及对线段覆盖问题的考查。

这类题目做的没几道,到目前的印象就是对区间进行某种排序,排序后便根据题目具体要求设计出相关的操作。

对于这道题贪心的证明:先将每头牛的最大SPF值进行降序排序(或者升序排序,我采用的是升序,都一样),这样首先保证了牛的最大SPF值是依次

往下降低的,对于任意两款护肤霜 x 和 y,SPF[X] > SPF[Y],如果当前牛两款都能用,那么对于下一头牛的使用情况会有三种,分别是:都能用,

y能用,x,y都不能用。而对于当前牛,只有选取当前对于它最大的护肤霜才能让接下来的牛使用尽量小的护肤霜。

但是这道题还有一个坑,就是每头牛的区间长度都不相同。因此在进行操作的时候,每次选择一头牛后就要进行遍历一遍,选取最大的合适的护肤霜。

如果不遍历直接选取会出现错误。

例如:

两头牛的SPF范围分别是:150——300, 

            160——290,

            而护肤霜分别是150, 160,

上面是按照从大到小排序过后的牛,使用护肤霜时,首先使用最大的,也就是160的护肤霜。那么接下来就要使用150的护肤霜,但实际上这时候就用不了了。

所以,在操作时需要遍历一遍未用的护肤霜,防止遗漏。

代码如下:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cmath>
 4 using namespace std;
 5 
 6 const int N = 2610;
 7 struct COW{
 8     int low, high;
 9 }cow[N];
10 struct SPF{
11     int v, sum;
12 }spf[N];
13 
14 bool cmp(COW a, COW b){
15     if(a.high != b.high)
16         return a.high < b.high;
17     else
18         return a.low < b.low;
19 }
20 bool cmp1(SPF a, SPF b){    
21     return a.v < b.v;
22 }
23 int main(){
24     int c, l;
25     cin >> c >> l;
26     for(int i = 1; i <= c; i ++) 
27         cin >> cow[i].low >> cow[i].high;
28     for(int i = 1; i <= l; i ++)
29         cin >> spf[i].v >> spf[i].sum;
30     
31     int cnt = 0;
32     sort(cow + 1, cow + c + 1, cmp);
33     sort(spf + 1, spf + l + 1, cmp1);
34 
35     //     if(spf[j].v >= cow[i].low && spf[j].v <= cow[i].high && spf[j].sum != 0){
36     //         cnt ++;
37     //         spf[j].sum --;
38     //         if(spf[j].sum == 0)
39     //             j ++;
40     //     }
41     //     else if(spf[j].v < cow[i].low)
42     //         j ++;
43     // }
44 
45     for(int i = 1; i <= c; i ++){
46         for(int j = 1; j <= l; j ++){
47             if(spf[j].v >= cow[i].low && spf[j].v <= cow[i].high && spf[j].sum){
48                 cnt ++;
49                 spf[j].sum --;
50                 break;
51             }
52         }
53     }
54     cout << cnt << endl;
55 
56     return 0;
57 }
原文地址:https://www.cnblogs.com/pureayu/p/13942772.html