poj 3614 Sunscreen
题意: 有一群奶牛要去晒日光浴,每头奶牛都有个自己"防晒值"(姑且这么叫吧==)区间min到max,如果太阳强度高于max就会被晒伤,但如果小于min就无法享受日光浴了。 现在L 种防晒霜,每种防晒霜都可以把太阳强度固定在一个spf值,并且最多可供cover头使用。问最多能有几头奶牛可以享受到日光浴而不被晒伤。
解题思路为贪心+优先队列:
按防晒霜的值从小到大排序。
按奶牛的min值从小到大排序。
从值最小的防晒霜开始枚举,将所有min值<=当前防晒霜值的奶牛的max值加入优先队列。 以这种顺序加入到优先队列的奶牛,故他们的min顺序肯定是从小到大的, 那么对于后面要枚举的所有防晒霜, 它们的值一定都是大于队列中所有奶牛的min值的。 因而就只要再考虑这些已入队的奶牛的max值是否大于当前防晒霜的值就好了, 所以在优先队列中只是加入奶牛的max值 不用再去管min值了。 满足上述要求后,即每次只要从优先队列中取出最小的max值就好了( 因为对于max值更大的而言 它的防晒能力的范围更广,所以应该将它留到更后面去用spf值更高的防晒霜 )。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <cstdlib> 7 #include <cctype> 8 #include <queue> 9 #include <stack> 10 #include <map> 11 #include <vector> 12 #include <set> 13 #include <utility> 14 #define ll long long 15 #define inf 0x3f3f3f3f 16 using namespace std; 17 18 typedef struct node1 19 { 20 int Min,Max; 21 } node1; 22 node1 a[2505]; 23 typedef struct node2 24 { 25 int spf,cover; 26 } node2; 27 node2 L[2505]; 28 int c,l; 29 bool cmp(node2 a,node2 b) 30 { 31 return a.spf<b.spf; 32 } 33 bool cc(node1 a,node1 b) 34 { 35 return a.Min<b.Min; 36 } 37 int main() 38 { 39 //freopen("input.txt","r",stdin); 40 scanf("%d%d",&c,&l); 41 for(int i=0; i<c; i++) 42 scanf("%d%d",&a[i].Min,&a[i].Max); 43 for(int i=0; i<l; i++) 44 scanf("%d%d",&L[i].spf,&L[i].cover); 45 sort(L,L+l,cmp); //把防晒霜的值从小到大排序 46 sort(a,a+c,cc); //把所有牛按Min值从小到大排 47 // 48 priority_queue<int,vector<int>,greater<int> > pq; 49 int cnt=0; 50 int p=0; 51 for(int i=0; i<l; i++) 52 { 53 while(a[p].Min<=L[i].spf&&p<c)//讲所有Min值小于该防晒霜的牛的Max值加入堆中 54 { 55 pq.push(a[p].Max); 56 p++; 57 } 58 while(!pq.empty()&&L[i].cover) //挑取堆中最小的Max值 59 { 60 int temp=pq.top();pq.pop(); 61 if(temp<L[i].spf) continue; 62 cnt++; 63 L[i].cover--; 64 } 65 } 66 printf("%d\n",cnt); 67 return 0; 68 }