poj3614 Sunscreen

贪心题。

如何找出正确的贪心策略呢?

我一开始是以为按照l排序,然后从1到n遍历,挑最大的满足的防晒霜。后来发现不行。挑最小的也不行。

看了题解发现是从n到1遍历。

为什么?

因为i-1的l比i的l承受能力要大些,我们只需考虑r!

而i+1的l比i的l承受能力要小一些!我们要两头考虑!失败!

然后是一些实现小细节了,包括手写二分......

 1 #include <cstdio>
 2 #include <algorithm>
 3 /// poj 3614
 4 using namespace std;
 5 const int N = 2510;
 6 int n, L;
 7 struct Cow{
 8     int a, b;
 9     bool operator < (const Cow &x) const {
10         if(this->a != x.a) {
11             return this->a < x.a;
12         }
13         return this->b < x.b;
14     }
15 }c[N], a[N];
16 int main() {
17     scanf("%d%d", &n, &L);
18     for(int i = 1; i <= n; i++) {
19         scanf("%d%d", &c[i].a, &c[i].b);
20     }
21     for(int i = 1; i <= L; i++) {
22         scanf("%d%d", &a[i].a, &a[i].b);
23     }
24     sort(c + 1, c + n + 1);
25     sort(a + 1, a + L + 1);
26     int ans = 0;
27     a[L + 1].a = 0x7f7f7f7f;
28     /*
29     printf("\n");
30     for(int i = 1; i <= n; i++) {
31         printf("%d %d\n", c[i].a, c[i].b);
32     }
33     printf("\n");
34     for(int i = 1; i <= L + 1; i++) {
35         printf("%d %d\n", a[i], sum[i]);
36     }
37     printf("\n");
38     */
39     for(int i = n; i >= 1; i--) {
40         int p, l = 1, r = L + 1;
41         while(l < r) {
42             p = (l + r) >> 1;
43             if(a[p].a <= c[i].b) {
44                 l = p + 1;
45             }
46             else r = p;
47         }
48         if(a[p].a > c[i].b) p--;
49         //printf("%d ", p);
50         while(!a[p].b && a[p].a >= c[i].a) {
51             p--;
52         }
53         //printf("%d\n", p);
54         if(p && a[p].a <= c[i].b && a[p].a >= c[i].a) {
55             ans++;
56             a[p].b--;
57         }
58     }
59     printf("%d", ans);
60     return 0;
61 }
AC代码

 

posted @ 2018-05-08 13:52  garage  阅读(80)  评论(0编辑  收藏  举报