题目描述
https://codeforces.com/contest/1430/problem/F
Solution
容易发现在能完成任务的情况下,如果可以不换弹夹就一定不换(最后一个弹夹不算的情况下显然
另外我们注意到对于一波来说,我们可以更新弹夹的时间是 $[l+1,r]$,所以一共能换 $r-l$ 次弹夹
那么对于一波我们还需要知道的信息就是在 $l$ 时我们有多少子弹
由于两波之间在端点处可能重叠,所以我们考虑倒着算出每波开始前至少要多少子弹
然后正着贪心即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <iostream> #include <cstdio> #include <vector> #include <cstring> #define maxn 2010 #define ll long long #define pb push_back #define INF 10000000000000000ll using namespace std;
int n; ll m;
struct node { int l, r, v; } a[maxn];
ll f[maxn]; int main() { cin >> n >> m; for (int i = 1; i <= n; ++i) cin >> a[i].l >> a[i].r >> a[i].v; for (int i = n; i; --i) { if (a[i].r == a[i + 1].l) f[i] = max(0ll, a[i].v + f[i + 1] - (a[i].r - a[i].l) * m); else f[i] = max(0ll, a[i].v - (a[i].r - a[i].l) * m); if (f[i] > m) return puts("-1"), 0; } ll ans = 0, tp = m; for (int i = 1; i <= n; ++i) { if (tp < f[i]) ans += tp, tp = m; ans += a[i].v; if (a[i].v >= tp) tp = m - (a[i].v - tp) % m; else tp -= a[i].v; } cout << ans << endl; return 0; }
|