种树

题目描述

现在我们国家开展新农村建设,农村的住房建设纳入了统一规划,统一建设,政府要求每一住户门口种些树。门口路边的地区被分割成块,并被编号成 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 BE,居民必须记住在指定区不能种多于区域地块数的树,所以 T ≤ E − B + l T \leq E-B+l TEB+l。居民们想种树的各自区域可以交叉。你的任务是求出能满足所有要求的最少的树的数量,尽量较少政府的支出。

输入格式

第一行包含数据 N N N M M M,区域的个数 ( 0 < N ≤ 30000 ) (0<N \leq 30000) (0<N30000),房子的数目 ( 0 < m ≤ 5000 ) (0 < m \leq 5000) (0<m5000)

下面的 m m m 行描述居民们的需要: B B B E E E T T T 0 < B ≤ E ≤ 30000 0 < B \leq E \leq 30000 0<BE30000 T ≤ E − B + 1 T \leq E-B+1 TEB+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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值