Vijos - [一本通 1.1 例 2]种树(贪心)

522 篇文章 3 订阅
58 篇文章 1 订阅

题目链接:https://vijos.org/d/ybttg/p/5c24aef1f41362c9e1912630
时间限制:1000 ms 内存限制:512 MiB

题目描述

某条街被划为 n n n条路段,这 n n n条路段依次编号为 1 … n 1\dots n 1n。每个路段最多可以种一棵树。现在居民们给出了 h h h组建议,每组建议包含三个整数 b , e , t b,e,t b,e,t,表示居民希望在路段 b b b e e e之间至少要种 t t t棵树。这些建议所给路段的区间可以交叉。请问:如果要满足所有居民的建议,至少要种多少棵树。

输入格式

第一行为 n n n,表示路段数。

第二行为 h h h,表示建议数。

下面 h h h行描述一条建议: b , e , t b, e, t b,e,t,用一个空格分隔。

输出格式

输出只有一个数,为满足所有居民的建议,所需要种树的最少数量。

样例输入

9
4
1 4 2
4 6 2
8 9 2
3 5 2

样例输出

5

限制与提示

30 % 30\% 30%的数据满足 0 < n ≤ 1000 , 0 < h ≤ 500 ; 0<n\le 1000,0<h\le 500; 0<n10000<h500
100 % 100\% 100%的数据满足 0 < n ≤ 3 × 1 0 4 , h ≤ 5000 , 0 < b ≤ e ≤ 3 × 1 0 4 , t ≤ e − b + 1 0<n\le 3 \times 10^4,h \le 5000,0<b \le e\le 3\times 10^4,t\le e-b+1 0<n3×104h50000<be3×104teb+1

解题思路

题意: n个居民希望在路段 b i b_i bi e i e_i ei之间至少要种 t i t_i ti棵树,区间可以交叉。求满足所有居民的建议,至少要种多少棵树。
思路: 贪心。先按结束位置从小到大排序,对每个区间依次处理,从前到后扫描这个区间,统计已选点的个数,若已选点的个数满足要求的点数,则跳过,否则从该区间由后向前扫描,添加缺少的覆盖点。

Accepted Code:

/* 
 * @Author: lzyws739307453 
 * @Language: C++ 
 */
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e4 + 5;
const int MAXM = 5e3 + 5;
struct edge {
    int s, e, t;
    bool operator < (const edge &s) const {
        return e < s.e;
    }
}p[MAXM];
bool vis[MAXN];
int main() {
    int n, m, ans = 0;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++)
        scanf("%d%d%d", &p[i].s, &p[i].e, &p[i].t);
    sort(p, p + m);
    for (int i = 0; i < m; i++) {
        int cnt = 0;
        for (int j = p[i].s; j <= p[i].e; j++)
            if (vis[j])
                cnt++;
        if (cnt >= p[i].t) continue;
        for (int j = p[i].e; j >= p[i].s && cnt < p[i].t; j--) {
            if (!vis[j]) {
                cnt++, ans++;
                vis[j] = true;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ityanger

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值