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$次即可.
```cpp
#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;
}
```\]