【排序不等式】 防晒
传送门
题解
\(c\)头牛,第 \(i\) 头可以接收的阳光范围为\(min[ i ], max[ i ]\),每头牛必须涂抹防晒霜,一共有\(L\)种,第 \(i\) 种可以让牛接收的阳光稳定在\(spf[i]\),有\(cover[ i ]\) 瓶。问最多可以有多少头牛晒日光浴。
数据范围
\(\begin{array}{l}1 \leq C, L \leq 2500 \\ 1 \leq \min S P F \leq \max S P F \leq 1000 \\ 1 \leq \operatorname{SPF} \leq 1000\end{array}\)
题解
将所有奶牛按照\(min\)从大到小排序,然后一次考虑每头奶牛
对于每头奶牛,扫描当前所有能用的防晒霜,选择值最大的防晒霜来使用
每一瓶\(spf\)是否可用,只会被\(min\)和\(max\)两个条件限制。
因为奶牛按照\(min\)递减排序,所以每一个不低于当前奶牛\(min\)的\(spf\)都不会低于后面的,
也就是任意两瓶防晒霜\(x\)和\(y\),且\(spf[ x ]<spf[ y ]\)后面只可能出现\(x\)和\(y\)都能用,
\(x\)和\(y\)都不能用或\(x\)能用,\(y\)不能用,这三种情况,
因此奶牛选择\(spf\)较大的\(y\)去使用,对于整体问题的影响显然比选择较小的x要好
每头奶牛对答案的贡献最多是\(1\),即使让当前放弃,后面使用,对答案的贡献也不会变大。
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define fi first
#define se second
typedef pair<int,int> pii;
const int N=3000;
pii cows[N];
map<int,int>spfs;
int c,l;
int main(){
scanf("%d%d",&c,&l);
rep(i,0,c) scanf("%d%d",&cows[i].fi,&cows[i].se);
rep(i,0,l){
int spf,cover;
scanf("%d%d",&spf,&cover);
spfs[spf]+=cover;
}
sort(cows,cows+c);
int ans=0;
spfs[1001] = spfs[0] = c;
per(i,0,c){
auto t = spfs.upper_bound(cows[i].se);
t--;
if(t->fi >= cows[i].fi){
ans++;
if(--t->se == 0)
spfs.erase(t);
}
}
printf("%d\n",ans);
}