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

猜你喜欢

转载自www.cnblogs.com/lylyl/p/11762247.html