洛谷 P2887

题目链接:P2887 [USACO07NOV]Sunscreen G

题目大意

给你一段区间,和几个数,然后选数, 数只能被选一遍且只能在区间范围(我说的可能是鸟语,尽量理解理解吧)

solution

首先看到这题,咋做啊? DP? 好想么?

然后我们优先考虑贪心. 先自己敲一个暴力, 如果觉得自己贪心对了,没时间证明的话,对拍. 拍个 \(10^5\) 组没有问题,那就基本上没有问题了.

那我们这题贪心怎么想呢? 贪心思路有很多种,我来简单介绍一下我的思路

我们可以将区间按左端点从大到小排序, 然后将防晒霜从大到小排序

那我们怎么证明这个贪心思路呢?对拍,证完了

我不会,行了吧

我们在拍完序之后, 如果现在阳光度最大的防晒霜不在这个区间内,那么之后的奶牛就更不可能满足了,但当这个能用时,那必然选了之后,后面的奶牛可选择范围更大

code:

/**
*    Author: Alieme
*    Data: 2020.8.25
*    Problem: Luogu P2887
*    Time: O(n^2)
*/
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>

#define ll long long
#define rr register

#define inf 1e9
#define MAXN 100010

using namespace std;

inline int read() {
	int s = 0, f = 0;
	char ch = getchar();
	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
	return f ? -s : s;
}

void print(int x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) print(x / 10);
	putchar(x % 10 + 48);
}

struct Spfi {
	int l;
	int r;
	bool operator < (const Spfi &b) const {return l > b.l;}
}		cow[MAXN];

struct Node{
	int spf;
	int num;
	bool operator < (const Node &b) const {return spf > b.spf;}
}des[MAXN];

int n, m, ans;

signed main() {
	n = read();
	m = read();
	for (rr int i = 1; i <= n; i++) {
		cow[i].l = read();
		cow[i].r = read();
	}
	for (rr int i = 1; i <= m; i++) {
		des[i].spf = read();
		des[i].num = read();
	}

	sort(cow + 1, cow + 1 + n);
	sort(des + 1, des + 1 + m);

	for (rr int i = 1; i <= n; i++) 
		for (rr int j = 1; j <= m; j++) 
			if (cow[i].l <= des[j].spf && cow[i].r >= des[j].spf && des[j].num) {
				des[j].num--;
				ans++;
				break;
			}
	print(ans);
}
posted @ 2020-08-25 22:12  Aliemo  阅读(130)  评论(0编辑  收藏  举报