贪心算法: 区间分组
c++
区间分组
/* 问题描述: 给定 N 个闭区间 [ai,bi],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。 输出最小组数。 输入格式: 第一行包含整数 N,表示区间数。 接下来 N 行,每行包含两个整数 ai,bi,表示一个区间的两个端点。 输出格式: 输出一个整数,表示最小组数。 数据范围: 1 ≤ N ≤ 105, −10^9 ≤ ai ≤ bi ≤ 10^9 解题思路: 区间按照左端点排序。然后,我们按照 1->n 遍历数组(最短点是依次增大的) 对于 i 我们假设当前已经存在 x 组区间,这些 x 组的区间,每组最靠右的区间为 [left_1, right_1], ..., [left_x, right_x] 根据我们的区间左端点排序,可知 segments[i].first > 任意 left_t, t属于[1, x]闭区间,也就是说,我们需要查看 right 的情况,判断 区间 i 是否可以放入集合中 倘若存在任意一个 right_j 严格小于 segments[i].first,则可以插入,否则需要增加一个新的区间集合。 倘若存在 right_j 个区间,我们需要选择哪一个呢?答案是任意一个,因为 segments[i].first <= segments[i+1].first, 这里面的任何一个区间对于剩下的 segments集合都是 ok 的。 但是,当然是选取最小的一个好了,因为使用堆维护,非常方便 证明可以通过替换法来证明,不过需要每次需要替换一整个后面的序列,由任何一个解交换为同样最优的解题思路给出的解。 */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <vector> using namespace std; const int N = 100010; typedef pair<int, int> PII; PII segments[N]; int n; bool cmp(const PII &t1, const PII &t2) { return t1.first <= t2.first; } int solution_one() { int res = 0; priority_queue<int, vector<int>, greater<int> > pque; sort(segments + 1, segments + n + 1, cmp); for (int i = 1; i <= n; i ++ ) { if (pque.empty() == true) { pque.push(segments[i].second); res += 1; } else if (pque.top() < segments[i].first) { pque.pop(); pque.push(segments[i].second); } else { pque.push(segments[i].second); res += 1; } } return res; // pque.size(); } int main() { // input 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 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!