这道题呢其实就一个十分普通的贪心,至于怎么实现就有很多种方法,由于用平衡树的人比较多,所以我在这里简单讲一下用#multiset#的做法。
简单谈一下心:我们可以分别将牛和草分别按照价格为第一关键字排序,然后我们在保证牛的价格小于等于当前草的价格的前提下,把牛要求的鲜嫩程度放在集合当中(集合是有序的),然后我们对于每一种草,我们只需要找到小于等于草的价格中牛需要的价格最大的,然后删除即可。
注意: 的排序本身就是按照 为第一关键字排序的。
参考代码:
#include <set>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define SG string
#define DB double
#define LL long long
using namespace std;
const LL Max=1e5+5;
multiset<LL>Set;
multiset<LL>::iterator It;
pair<LL,LL>A[Max],B[Max];
LL N,M,Cur=1,Ans;
inline LL Read(){
LL X=0;char CH=getchar();bool F=0;
while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
return F?-X:X;
}
inline void Write(LL X){
if(X<0)X=-X,putchar('-');
if(X>9)Write(X/10);
putchar(X%10+48);
}
int main(){
LL I,J,K;
N=Read(),M=Read();
for(I=1;I<=N;I++){
A[I].first=Read(),A[I].second=Read();
}
sort(A+1,A+1+N);
for(I=1;I<=M;I++){
B[I].first=Read(),B[I].second=Read();
}
sort(B+1,B+1+M);
for(I=1;I<=M;I++){
while(Cur<=N&&A[Cur].first<=B[I].first){
Set.insert(-A[Cur].second);Cur++;
}
It=Set.lower_bound(-B[I].second);
if(It!=Set.end()){
Ans+=B[I].first;Set.erase(It);
}
}
if(Cur==N+1&&Set.size()==0){
Write(Ans);
} else {
puts("-1");
}
return 0;
}