csp信奥赛C++高频考点专项训练之贪心算法 --【区间贪心】:种树

csp信奥赛C++高频考点专项训练之贪心算法 --【区间贪心】:种树

题目背景

一条街的一边有几座房子,因为环保原因居民想要在路边种些树。

题目描述

路边的地区被分割成块,并被编号成 1 , 2 , ... , n 1, 2, \ldots,n 1,2,...,n。每个部分为一个单位尺寸大小并最多可种一棵树。

每个居民都想在门前种些树,并指定了三个号码 b b b, e e e, t t t。这三个数表示该居民想在地区 b b b 和 e e e 之间(包括 b b b 和 e e e)种至少 t t t 棵树。

居民们想种树的各自区域可以交叉。你的任务是求出能满足所有要求的最少的树的数量。

输入格式

输入的第一行是一个整数,代表区域的个数 n n n。

输入的第二行是一个整数,代表房子个数 h h h。

第 3 3 3 到第 ( h + 2 ) (h + 2) (h+2) 行,每行三个整数,第 ( i + 2 ) (i + 2) (i+2) 行的整数依次为 b i , e i , t i b_i, e_i, t_i bi,ei,ti,代表第 i i i 个居民想在 b i b_i bi 和 e i e_i ei 之间种至少 t i t_i ti 棵树。

输出格式

输出一行一个整数,代表最少的树木个数。

输入输出样例 1
输入 1
复制代码
9
4
1 4 2
4 6 2
8 9 2
3 5 2
输出 1
复制代码
5
数据规模与约定

对于 100 % 100\% 100% 的数据,保证:

  • 1 ≤ n ≤ 3 × 10 4 1 \leq n \leq 3 \times 10^4 1≤n≤3×104, 1 ≤ h ≤ 5 × 10 3 1 \leq h \leq 5 \times 10^3 1≤h≤5×103。
  • 1 ≤ b i ≤ e i ≤ n 1 \leq b_i \leq e_i \leq n 1≤bi≤ei≤n, 1 ≤ t i ≤ e i − b i + 1 1 \leq t_i \leq e_i - b_i + 1 1≤ti≤ei−bi+1。

思路分析

本题要求满足所有区间"至少种 t 棵树"的最少总植树数。核心贪心策略:
将区间按右端点从小到大排序,对于每个区间,先统计已种树数量,若不足则优先在区间右端空闲位置补种。这样每棵树尽可能被后续区间覆盖,从而减少总数。

采用朴素标记数组实现:

  1. 读取 n(区域数)、h(居民数)及每个居民的 b, e, t
  2. 按右端点 e 升序排序所有区间。
  3. 遍历每个区间:
    • 统计区间内已种树数量 cnt(通过遍历区间扫描 used 数组)。
    • cnt < t,从右向左遍历区间,遇到空闲位置就种树(标记 used[j]=true),并增加答案,直到满足数量。
  4. 输出总种树数。

时间复杂度 :最坏 O(h × n),约 5000×30000=1.5e8,在实际数据下可 AC(因为区间重叠多,扫描次数远小于最坏值)。
空间复杂度:O(n)。

代码实现

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

const int N=30010;//最大区域数

struct Node{
    int b,e,t;
}a[5010];

bool used[N];//标记每个位置是否已种树

bool cmp(Node x,Node y){
    return x.e<y.e;//按右端点升序
}
int main(){
    int n,h;cin>>n>>h;//n:区域数,h:居民数
    
    for(int i=1;i<=h;i++)cin>>a[i].b>>a[i].e>>a[i].t;
    
    sort(a+1,a+h+1,cmp);//区间排序
    
    int ans=0;//总植树数
    for(int i=1;i<=h;i++){//处理每个区间
        int b=a[i].b,e=a[i].e,t=a[i].t;
        int cnt=0;//统计区间内已有树数
        for(int j=b;j<=e;j++)if(used[j])cnt++;//扫描统计
        for(int j=e;j>=b&&cnt<t;j--){//从右向左补种
            if(!used[j]){//空闲位置
                used[j]=true;//种树
                cnt++;//已种数增加
                ans++;//总树数加1
            }
        }
    }
    cout<<ans<<endl;//输出最少树木个数
    return 0;
}

功能分析

  • 输入解析 :读取区域总数、居民个数以及每个居民要求的区间 [b,e] 和至少种树数 t
  • 排序预处理:按区间右端点升序排列,确保后续处理中,靠右的树木能覆盖更多未处理的区间。
  • 贪心补种
    • 对于当前区间,先统计该区间内已种树的数量(通过遍历 used 数组)。
    • 若数量不足,则从区间最右端开始向左寻找空闲位置,每找到一个就种一棵树,直到满足该区间需求。
  • 结果输出:累加所有种下的树木,输出最小值。

各种学习资料,助力大家一站式学习和提升!!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}

【秘籍汇总】(完整csp信奥赛C++学习资料):

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

https://edu.csdn.net/course/detail/41081 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转

4、csp信奥赛冲刺一等奖有效刷题题解:

CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
hi_ro_a2 小时前
C++ 哈希表封装 unordered_map /unordered_set
数据结构·c++·算法·哈希算法
c++之路2 小时前
C++ 动态内存
java·jvm·c++
Jasmine_llq6 小时前
《B4447 [GESP202512 二级] 环保能量球》
数据结构·算法·数学公式计算(核心)·整数除法算法·多组数据循环处理·输入输出算法·简单模拟算法
蔡大锅6 小时前
🔥 在线学习算力平台推荐-Hyper.AI
人工智能·算法
老唐7776 小时前
常见经典十大大机器学习算法分类与总结
人工智能·深度学习·神经网络·学习·算法·机器学习·ai
橘颂TA7 小时前
【Linux】读写锁
大数据·linux·开发语言·c++·读写锁
霍田煜熙7 小时前
HuoTian的两赛vlog(游记)~(2026.04.26写)
c++·奥数·双赛·vlog
wearegogog1237 小时前
动态时间规整(DTW):跨越时间维度的相似性度量
算法
ECT-OS-JiuHuaShan7 小时前
渡劫代谢,好事多磨
数据库·人工智能·科技·学习·算法·生活