题意:c头奶牛,每一头奶牛有一个忍耐区间
,现在给出
种忍耐值以及对应的数量,经过最优的分配,c头奶牛各获得一个忍耐值,问最多有多少头奶牛的忍耐值在其忍耐区间内?
思路:
情况一:
我们考虑,假如有一个忍耐值位于这个区间内部
1、假定落在区间 内
那我们贪心地想,把这个忍耐值给第二头奶牛更适宜
2、其余情况
只有一种奶牛符合条件,不需要贪心考虑
情况二:
对于这种情况,忍耐值不管是什么,都最多只有一头奶牛符合
所以,不需要贪心考虑
情况三:
1、忍耐值位于区间
显然,按照贪心思路考虑,给第一头奶牛更适宜
2、其余情况
只有一头奶牛符合,不需要贪心
综合得知,我们每次把忍耐值给某个奶牛,这个奶牛的忍耐区间右端点与该忍耐值最接近
代码实现
1、忍耐区间按右端点递增排序
2、忍耐值递增排序
3、枚举忍耐值,从头到尾check每一个忍耐区间(保证与忍耐值最接近)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 2500 + 5;
struct node{
int l, r;
}a[maxn];
struct Node{
int val, num;
}s[maxn];
int c, l; bool vis[maxn];
bool cmp(node b, node c){
if(b.r == c.r) return b.l < c.l;
return b.r < c.r;
}
bool cmp1(Node b, Node c){
if(b.val == c.val) return b.num > c.num;
return b.val < c.val;
}
int main(){
scanf("%d%d", &c, &l);
for(int i = 1; i <= c; i++){
scanf("%d%d", &a[i].l, &a[i].r);
}
sort(a + 1, a + c + 1, cmp);
for(int i = 1; i <= l; i++){
scanf("%d%d", &s[i].val, &s[i].num);
}
sort(s + 1, s + l + 1, cmp1);
int ans = 0, j, num, val;
for(int i = 1; i <= l; i++){
num = s[i].num; val = s[i].val;
for(j = 1; j <= c; j++){
if(num == 0) break;
if(!vis[j] && val >= a[j].l && val <= a[j].r){
ans++;
num--;
vis[j] = true;
}
}
}
printf("%d\n", ans);
return 0;
}