这题的模型是给你一些线段和一些点,每个点的使用次数都是有一定限制的,每条线段只能被标记一次,求最多有多少条线段被标记。
做法是将奶牛按照阳光强度的最小值从小到大排序。将防晒霜也按照能固定的阳光强度从小到大排序。
从最小的防晒霜枚举,将所有符合 最小值小于等于该防晒霜的 奶牛的 最大值 放入优先队列之中。
然后优先队列是小值先出
所以就可以将这些最大值中的最小的取出来。更新答案。
//216K 16MS
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
typedef pair<int, int> pii;
pii cow[2500+5], bot[2500+5];
int main(){
int C, L;
while(scanf("%d %d", &C, &L) != EOF){
priority_queue< int, vector<int>, greater<int> > pque;
for(int i=0; i<C; i++)
scanf("%d %d", &cow[i].first, &cow[i].second);
for(int i=0; i<L; i++)
scanf("%d %d", &bot[i].first, &bot[i].second);
sort(cow, cow+C);
sort(bot, bot+L);
int j = 0, res = 0;
for(int i=0; i<L; i++){ //考虑第i个瓶子
while(j < C && cow[j].first <= bot[i].first){ //j表示第j头牛
pque.push(cow[j].second); //把所有可能被该点标记的线段放入队列中
j++;
}
while(!pque.empty() && bot[i].second){ //使第i个点尽可能多地去标记线段
int e = pque.top(); pque.pop(); //取出队列里末端点最小的线段
if(e < bot[i].first) continue; //如果该线段都不能被这个点标记,那么肯定不能被后面的点标记了
bot[i].second--;
res++;
}
}
printf("%d\n", res);
}
return 0;
}