题目描述
现在我们国家开展新农村建设,农村的住房建设纳入了统一规划,统一建设,政府要求每一住户门口种些树。门口路边的地区被分割成块,并被编号成 1... N 1...N 1...N。每个部分为一个单位尺寸大小并最多可种一棵树。每个居民房子门前被指定了三个号码 B B B, E E E, T T T。这三个数表示该居民想在 B B B 和 E E E 之间最少种 T T T 棵树。当然, B ≤ E B \leq E B≤E,居民必须记住在指定区不能种多于区域地块数的树,所以 T ≤ E − B + l T \leq E-B+l T≤E−B+l。居民们想种树的各自区域可以交叉。你的任务是求出能满足所有要求的最少的树的数量,尽量较少政府的支出。
输入格式
第一行包含数据 N N N, M M M,区域的个数 ( 0 < N ≤ 30000 ) (0<N \leq 30000) (0<N≤30000),房子的数目 ( 0 < m ≤ 5000 ) (0 < m \leq 5000) (0<m≤5000);
下面的 m m m 行描述居民们的需要: B B B, E E E , T T T, 0 < B ≤ E ≤ 30000 0 < B \leq E \leq 30000 0<B≤E≤30000, T ≤ E − B + 1 T \leq E-B+1 T≤E−B+1。
输出格式
输出一个数,为满足所有居民的要求,所需要种树的最少数量。
输入样例
9 4
3 5 2
1 4 2
4 6 2
8 9 2
输出样例
5
解题思路
- 先按照区间结束位置( E E E)从小到大排序;
- 对每个区间依次处理:
- 从前到后扫描这个区间,统计已选点的个数;
- 若已选点的个数超过了要求的点数,则continue;
- 否则从该区间有后向前扫描,添加缺少的覆盖点;
- 输出ans;
标准程序
#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
struct node {
int b, e, t;
} a[5005];
int n, m;
bool st[30005];
bool cmp(node x, node y) { return x.e < y.e; }
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) scanf("%d%d%d", &a[i].b, &a[i].e, &a[i].t);
sort(a + 1, a + m + 1, cmp);
int ans = 0;
for (int i = 1; i <= m; i++) {
int k = 0;
for (int j = a[i].b; j <= a[i].e; j++)
if (st[j]) k++;
if (k >= a[i].t) continue;
for (int j = a[i].e; j >= a[i].b; j--)
if (!st[j]) {
st[j] = true;
ans++;
k++;
if (k == a[i].t) break;
}
}
printf("%d\n", ans);
return 0;
}