[USACO09FEB]庙会班车Fair Shuttle

首先我们要明确一点:每一个小组中的奶牛不一定要行动一致!(即可以只上一部分)(我在这里卡了好久艹)

所以易得出一个贪心策略:尽量将班车装满.但好像有些问题.

举个栗子:

\(3\ 10\ 5\\1\ 10\ 5\\1\ 5\ 5\\6\ 10\ 5\)

如果我们按照上面的策略,答案就将是\(5\),但显然答案为\(10\),

但是如果我们将输入顺序改变一下:

\(3\ 10\ 5\\1\ 5\ 5\\6\ 10\ 5\\1\ 10\ 5\)

答案就对了.这提示我们要将输入排序.

我们可以对于每段区间的右端点从小到大排序,对于当前区间,能上多少奶牛上多少一定不劣.

于是记一下能上多少奶牛,\(ans\)累加即可.

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define il inline
#define rg register
#define gi read<int>
using namespace std;
const int N = 2e4 + 10, K = 5e4 + 10;
typedef long long ll;
struct LL{
	int l, r, v;
	il bool operator < (LL rhs) {
		return r - l < rhs.r - rhs.l;
	}
}s[K];
template<class TT>
il TT read() {
	TT o = 0, fl = 1; char ch = getchar();
	while (!isdigit(ch)) fl ^= ch == '-', ch = getchar();
	while (isdigit(ch)) o = o * 10 + ch - '0', ch = getchar();
 	return fl ? o : -o;
}
int kk, k, n, c, ans, bus[N];
int main() {
	kk = gi(), n = gi(), c = gi();
	for (int i = 1; i <= kk; ++i){
		int L = gi(), R = gi(), V = gi();
		if (V > c) V = c;
		s[++k] = (LL){L, R, V};
	}
	sort(s + 1, s + k + 1);
	for (int i = 1; i <= k; ++i) {
		int minn = s[i].v;
		for (int j = s[i].l; j < s[i].r; ++j) {
			minn = min(minn, c - bus[j]);
			if (!minn) break;
		}
		if (!minn) continue;
		ans += minn;
		for (int j = s[i].l; j < s[i].r; ++j)
			bus[j] += minn;
	}
	printf("%d\n", ans);
	return 0;
}
posted @ 2019-10-29 23:08  wuhan2005  阅读(134)  评论(0编辑  收藏  举报