110. 防晒
题目链接
110. 防晒
有 \(C\) 头奶牛进行日光浴,第 \(i\) 头奶牛需要 \(\min S P F[i]\) 到 \(\max S P F[i]\) 单位强度之间的阳光。
每头奶牛在日光浴前必须涂防晒霜,防晒霜有 \(L\) 种,涂上第 \(i\) 种之后,身体接收到的阳光强度就会稳定为 \(S P F[i]\) ,第 \(i\) 种防晒霜有 \(\operatorname{cover}[i]\) 瓶。
求最多可以满足多少头奶牛进行日光浴。
输入格式
第一行输入整数 \(C\) 和 \(L\) 。
接下来的 \(C\) 行,按次序每行输入一头牛的 \(\min S P F\) 和 \(\max S P F\) 值,即第 \(i\) 行输入 \(\min S P F[i]\) 和 \(\max S P F[i]\) 。
再接下来的 \(L\) 行,按次序每行输入一种防晒霜的 \(S P F\) 和 cover 值,即第 \(i\) 行输入 \(S P F[i]\) 和 \(\operatorname{cover}[i]\) 。
每行的数据之间用空格隔开。
输出格式
输出一个整数,代表最多可以满足奶牛日光浴的奶牛数目。
数据范围
\(1 \leq C, L \leq 2500,\)
\(1 \leq \min S P F \leq \max S P F \leq 1000,\)
\(1 \leq S P F \leq 1000\)
解题思路
贪心
贪心策略:将奶牛按左端点逆序排序,遍历一遍,每次寻找尽量大的防晒霜
对于当前奶牛,选择一块防晒霜,由于左端点逆序,所以如果当前防晒霜满足条件,则不用考虑后面奶牛的左端点,只用考虑右端点,由于一块防晒霜和一个奶牛对答案的贡献都至多为 \(1\),所以对于当前奶牛能选的话尽量选上,考虑选择尽量大的防晒霜是为了留有小的防晒霜可能后面的奶牛会用到,结果会更好
- 时间复杂度:\(O(nlogn)\)
代码
// Problem: 防晒
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/description/112/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
// %%%Skyqwq
#include
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long LL;
typedef pair PII;
typedef pair PLL;
template bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
const int N=2505;
PII cow[N];
map mp;
int c,l;
int main()
{
cin>>c>>l;
for(int i=1;i<=c;i++)cin>>cow[i].fi>>cow[i].se;
while(l--)
{
int x,y;
cin>>x>>y;
mp[x]+=y;
}
sort(cow+1,cow+1+c);
int res=0;
for(int i=c;i;i--)
{
auto p=mp.upper_bound(cow[i].se);
if(p==mp.begin())continue;
p--;
if(p->fi>=cow[i].fi)
{
res++;
if(--p->se==0)mp.erase(p);
}
}
cout<