Luogu P2889 [USACO07NOV]Milking Time S

题目描述

https://www.luogu.com.cn/problem/P2889

简单dp题复习

Solution

离散化之后每个区间按照左端点排序

dp数组记一下右端点即可

时间复杂度 $O(n^2)$

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <cstdio>
#include <algorithm>
#define maxn 1010
#define cn const node
using namespace std;

int n, m, t;

struct node {
int l, r, w;

friend bool operator < (cn &u, cn &v) {
if (u.l == v.l) return u.r < v.r;
return u.l < v.l;
}
} a[maxn];


int b[maxn * 2], cnt;
void init_hash() {
for (int i = 1; i <= n; ++i) b[i] = a[i].l, b[i + n] = a[i].r;
sort(b + 1, b + 2 * n + 1); cnt = unique(b + 1, b + 2 * n + 1) - b - 1;
for (int i = 1; i <= n; ++i) {
a[i].l = lower_bound(b + 1, b + cnt + 1, a[i].l) - b;
a[i].r = lower_bound(b + 1, b + cnt + 1, a[i].r) - b;
}
}

int f[maxn][maxn * 2];

int main() {
cin >> m >> n >> t;
for (int i = 1; i <= n; ++i) cin >> a[i].l >> a[i].r >> a[i].w;
sort(a + 1, a + n + 1); init_hash();
for (int i = 1; i <= n; ++i) {
f[i][a[i].r] = a[i].w;
for (int j = 1; j <= cnt; ++j) {
if (b[j] + t <= b[a[i].l])
f[i][a[i].r] = max(f[i][a[i].r], f[i - 1][j] + a[i].w);
f[i][j] = max(f[i][j], f[i - 1][j]);
}
}
int ans = 0;
for (int i = 1; i <= cnt; ++i) ans = max(ans, f[n][i]);
cout << ans << endl;
return 0;
}