题目链接:#10001. 「一本通 1.1 例 2」种树 - 题目 - LibreOJ (loj.ac)
思路:与活动安排排序方式相同,将路段e按从小到大进行sort排序。首先统计每个区间所选种树点的个数,如果所选点的个数等于所需至少选的个数,直接continue到下一个区间。因为所给路段的区间可以交叉,所以从右端点添加没有达到题目所要选的最少个数,最后判断每个区间是否满足要求,输出答案。
AC代码
#include <bits/stdc++.h>
#define endl "\n"
#define pb push_back
#define int long long
#define inf 0x3f3f3f3f
#define all(v) v.begin(), v.end()
using namespace std;
const int N = 3e4 + 10;
int n, h;
bool st[N];
struct pp
{
int b, e, t;
} q[N];
bool cmp(pp x, pp y) {
return x.e < y.e;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> h;
for (int i = 1; i <= h; i++) {
cin >> q[i].b >> q[i].e >> q[i].t;
}
sort(q + 1, q + 1 + h, cmp);
for (int i = 1; i <= h; i++) {
int cnt = 0;
for (int j = q[i].b; j <= q[i].e; j++) {
if (st[j]) cnt++;
if (cnt == q[i].t) break;
}
if (cnt < q[i].t) {
for (int j = q[i].e; cnt < q[i].t; j--) {
if (!st[j]) {
st[j] = true;
cnt++;
}
}
}
}
int ans = 0;
for (int i = 1; i <= n; i++) {
if (st[i]) ans++;
}
cout << ans;
return 0 ^ 0;
}