poj3614 Sunscreen
贪心题。
如何找出正确的贪心策略呢?
我一开始是以为按照l排序,然后从1到n遍历,挑最大的满足的防晒霜。后来发现不行。挑最小的也不行。
看了题解发现是从n到1遍历。
为什么?
因为i-1的l比i的l承受能力要大些,我们只需考虑r!
而i+1的l比i的l承受能力要小一些!我们要两头考虑!失败!
然后是一些实现小细节了,包括手写二分......
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }