[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;
}