【排序不等式】 防晒

传送门

题解

\(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);
}   

posted @ 2020-06-18 08:25  Hyx'  阅读(120)  评论(0编辑  收藏  举报