贪心算法: 区间覆盖
C++
区间覆盖
/* 问题描述: 给定 N 个闭区间 [ai,bi] 以及一个线段区间 [s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。 输出最少区间数,如果无法完全覆盖则输出 −1。 输入格式: 第一行包含两个整数 s 和 t,表示给定线段区间的两个端点。 第二行包含整数 N,表示给定区间数。 接下来 N 行,每行包含两个整数 ai,bi,表示一个区间的两个端点。 输出格式: 输出一个整数,表示所需最少区间数。 如果无解,则输出 −1。 数据范围: 1 ≤ N ≤ 105, −10^9 ≤ ai ≤ bi ≤ 10^9, −10^9 ≤ s ≤ t ≤ 10^9 解题思路: 问题是在于如何覆盖 [s, t] 区间,也就是不断寻找在覆盖 s 的前提下,尽可能的向右走。 然后更新 目标为 [max_right, t],不断寻找,直到大于等于 t,或者是无解。 尽可能的向右走,要求我们区间左端点排序好一些,因为右端点为第一关键字排序的话,寻找max_right 复杂度较高。 左端点为第一关键字排序,可以使用双指针算法很快求解出 max_right。 */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 100010, INF = 0x3f3f3f3f; typedef pair<int, int> PII; PII segments[N]; int n; int l, r; bool cmp(const PII &t1, const PII &t2) { return t1.first < t2.first; } int solution_one() { // sort sort(segments + 1, segments + n + 1, cmp); int ret = 0; int limit = l; int max_right = -INF; for (int i = 1; i <= n; i ++ ) { // 寻找当前 limit 的最大区间覆盖 max_right = -INF; int j; for (j = i; j <= n; j ++ ) { if (segments[j].first <= limit) { max_right = max(max_right, segments[j].second); } else { break; } } i = j - 1; if (max_right == -INF) { return -1; } else { ret += 1; limit = max_right; if (limit >= r) { break; } } } if (limit >= r) { return ret; } else { return -1; } } int main() { // input scanf("%d%d", &l, &r); scanf("%d", &n); for (int i = 1; i <= n; i ++ ) { scanf("%d%d", &segments[i].first, &segments[i].second); } int res = solution_one(); printf("%d\n", res); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)