P5894 [IOI2013]robots 机器人

"当苦夏簌簌扑着扇,听过最后一声蝉"

蛮不错的贪心,不过灰题真的香

首先为啥具有二分性呢?因为如果我们k秒可以完成那么k+1秒也一定可以完成

然后我们就可以考虑二分一个ans,然后题目中的限制可以建图跑网络流,然后一看数据范围直接放弃

所以网络流不过就是贪心,因为只有两维我们能很简单的贪一下qwq

对于弱机器人,我们把玩具按照重量排序,然后每个机器人尽可能拿能拿的体积大的,并且机器人从小到大去选择,可以拿堆维护

剩下的玩具如果有小机器人拿不了的就完蛋

看上去很简单,但是要小心我们堆里存的东西一定是当前可以拿的...

吐槽一下神翻译小机器人和弱机器人让我笑好久

以及特判一些情况/xyx

code


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int MAXN = 1e6 + 7;
using namespace std;
int n, A, B, ans = -1;
int a[MAXN], b[MAXN];
struct rec {
	int w, s;
	bool operator<(const rec &x) {
		if(w == x.w)return s < x.s;
		return w < x.w;
	}
} t[MAXN];

priority_queue<int> heap;
inline int chk(int x) {
	int l = 1, j = 1;
	while(!heap.empty())heap.pop();
	for(int i = 1; i <= n; ++i) {
		if(l > A) {
			heap.push(t[i].s);
			continue;
		}
		if(a[l] > t[i].w) {
			heap.push(t[i].s);
		} else {
			while(a[l] <= t[i].w && l <= A) {
				j = 1;
				while(j <= x && !heap.empty()) {
					++j;
					heap.pop();
				}
				++l;
			}
			heap.push(t[i].s);
		}
	}
	for(int i = l; i <= A; ++i) {
		j = 1;
		while(j <= x && !heap.empty()) {
			++j;
			heap.pop();
		}
	}
    //特判有的强机器人能拿光所有的
	for(int i = B; i >= 1; --i) {
		j = 1;
		while(j <= x && !heap.empty()) {
			++j;
			l = heap.top();
			if(l >= b[i])return 0;
			heap.pop();
		}
		if(heap.empty())break;
	}
	if(!heap.empty())return 0;
	//还有没空的
	return 1;
}

int main() {
	scanf("%d%d%d", &A, &B, &n);
	for(int i = 1; i <= A; ++i)scanf("%d", &a[i]);
	sort(a + 1, a + A + 1);
	for(int i = 1; i <= B; ++i)scanf("%d", &b[i]);
	sort(b + 1, b + B + 1);
	for(int i = 1; i <= n; ++i)scanf("%d%d", &t[i].w, &t[i].s);
	sort(t + 1, t + n + 1);
	int L = 1, R = n, mid;
	while(L <= R) {
		mid = (L + R) >> 1;
		if(chk(mid)) {
			ans = mid;
			R = mid - 1;
		} else {
			L = mid + 1;
		}
	}
	printf("%d\n", ans);
	return 0;
}