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; } ```\]

posted @ 2019-10-19 17:17  wuhan2005  阅读(97)  评论(0编辑  收藏  举报