思路:贪心。我们先定义结点\(node\)存储所有长和宽,我们用\(l\)存长\(w\)存宽\(ok\)存是否是容器,\(ok = 1\)表示是容器,\(ok = 0\)表示是巧克力,我们先按照以下的方式排序:\(w\)从大到小,如果\(w\)一样,\(l\)从大到小排序,如果\(l,w\)都一样,那么按照\(ok\)进行排序。然后遍历整个\(vector\),如果是容器就放到\(multiset\)里面,如果是巧克力就在\(multiset\)里面二分出第一个\(l\)大于当前\(l\)的那个,因为这时候的\(w\)一定满足条件,这样二分匹配是最优的。
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
struct node{
int w, l, ok;
bool operator<(node&a){
if(w > a.w) return true;
if(w < a.w) return false;
if(l > a.l) return true;
if(l < a.l) return false;
return ok > a.ok;
}
};
int n, m;
vector<node>q;
const int N = 200010;
int a[N], b[N], a1[N], b1[N];
multiset<int>s;
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i ++ ){
cin >> a[i];
}
for(int i = 1; i <= n; i ++ ){
cin >> b[i];
}
for(int i = 1; i <= m; i ++ ){
cin >> a1[i];
}
for(int i = 1; i <= m; i ++ ){
cin >> b1[i];
}
for(int i = 1; i <= n; i ++ ){
q.pb({a[i], b[i], 0});
}
for(int i = 1; i <= m; i ++ ){
q.pb({a1[i], b1[i],1});
}
sort(q.begin(),q.end());
for(auto[x, y, z] : q){
if(z == 1){
s.insert(y);
}else{
auto it = s.lower_bound(y);
if(it == s.end()){
puts("No");
return 0;
}else{
s.erase(it);
}
}
}
puts("Yes");
return 0;
}