luoguP1315 观光公交

首先,我们可以对于每一个景点,求出从这个景点出发的乘客最晚到达的时间.记为\(T[i]\)

再记\(Tim[i]]\)表示公交车从景点\(i\)出发的最小时间.

\[\therefore Tim[i]=\max(Tim[i-1],T[i-1])+d[i-1]\].

同时,我们可以求出在每一个点下车的乘客数量\(z_i\).

我们再对每一个氮气加速器进行处理.

对于每一条连接两个景点的路\(d_i\),我们可以求出在\(d_i\)使用一个氮气加速器最多能够影响到的最远的景点\(nxt_i\).

于是我们可以对每一个\(d_i\),算出在其使用氮气加速器的利润\(\sum^{nxt_i}_{j=d_i}z_j\),取出最大值,并将\(d_i\)自减.

重复\(k\)次即可.

#include<bits/stdc++.h>
#define il inline
#define rg register
#define gi read<int>
using namespace std;
const int N = 1e3 + 10, M = 1e4 + 10;
template<class TT>
il TT read() {
    TT o = 0,fl = 1; char ch = getchar();
    while (!isdigit(ch) && ch != '-') ch = getchar();
    if (ch == '-') fl = -1, ch = getchar();
    while (isdigit(ch)) o = o * 10 + ch - '0', ch = getchar();
    return fl * o;
}
int n, m, k, maxn, id, ans, d[N], a[M], b[M], t[M], z[N], T[N], nxt[N];
int main() {
    n = gi(), m = gi(), k = gi();
    for (int i = 1; i < n; ++i) d[i] = gi();
    for (int i = 1; i <= m; ++i) {
        t[i] = gi(), a[i] = gi(), b[i] = gi();
        ans -= t[i];
        T[a[i]] = max(T[a[i]], t[i]); ++z[b[i]];
    }
    for (int i = 2; i <= n; ++i) z[i] += z[i - 1];
    t[1] = 0;
    for (int i = 2; i <= n; ++i) t[i] = max(t[i - 1], T[i - 1]) + d[i - 1];
    for (int i = 1; i <= m; ++i) ans += t[b[i]];
    for (int i = k; i; --i) {
        maxn = 0, nxt[n] = nxt[n - 1] = n;
        for (int j = n - 2; j; --j)
            if (t[j + 1] <= T[j + 1]) nxt[j] = j + 1;
            else nxt[j] = nxt[j + 1];
        for (int j = 1; j <= n; ++j)
            if (z[nxt[j]] - z[j] > maxn && d[j])
                maxn = z[nxt[j]] - z[j], id = j;
        d[id]--; ans -= maxn;
        for (int j = 2; j <= n; ++j) t[j] = max(t[j - 1], T[j - 1]) + d[j - 1];
    }
    printf("%d\n", ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lylyl/p/11704505.html
今日推荐