目录
- 1 基础知识
- 2 模板
- 3 工程化
1 基础知识
暂无。。。
2 模板
暂无。。。
3 工程化
题目1:区间选点。给你N个区间,让你在数轴上选一些点,要求N个区间中至少有一个点被选出。求选一些点的最少数目。
解题思路:贪心,按照右端点排序,每次选择右端点,维护一个res
和右端点right
即刻,如果当前区间左端点大于right
,则更新right
,res
自增。
C++代码如下,
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;int main() {int n;cin >> n;vector<pair<int,int>> nums;for (int i = 0; i < n; ++i) {int a, b;cin >> a >> b;nums.emplace_back(a,b);}sort(nums.begin(), nums.end(), [](const pair<int,int> a, const pair<int,int> b) {return a.second < b.second;});int res = 0;int right = -2e9;for (auto [x,y] : nums) {if (x > right) {res += 1;right = y;}}cout << res << endl;return 0;
}
题目2:求最大不相交区间数。给定N个区间,你可以选择一些区间,要求这些区间不能相交,求区间的最大数目。
解题思路:同题目1的解题思路。
C++代码如下,
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;int main() {int n;cin >> n;vector<pair<int,int>> nums;for (int i = 0; i < n; ++i) {int a, b;cin >> a >> b;nums.emplace_back(a,b);}sort(nums.begin(), nums.end(), [](const pair<int,int> a, const pair<int,int> b) {return a.second < b.second;});int res = 0;int right = -2e9;for (auto [l, r] : nums) {if (l > right) {res += 1;right = r;}}cout << res << endl;return 0;
}
题目3:给你N个区间,请将它们分成若干组,要求每组内部两两区间互不相交,求组数目的最小值。
关键步骤介绍如下:
- 将区间按照左端点排序。
- 定义一个小根堆
heap
,用来存储每个组中所有区间右端点的最大值。 - 遍历每个区间[l, r],如果堆顶大于等于l,则将r插入到堆中;否则弹出堆顶,再将r插入到堆中。
- 最终答案等价于堆中的元素数目。
C++代码如下,
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>using namespace std;int main() {int n;cin >> n;vector<pair<int,int>> nums;for (int i = 0; i < n; ++i) {int a, b;cin >> a >> b;nums.emplace_back(a,b);}sort(nums.begin(), nums.end());priority_queue<int, vector<int>, greater<int>> heap;for (auto [l, r] : nums) {if (heap.empty() || heap.top() >= l) {heap.push(r);} else {heap.pop();heap.push(r);}}cout << heap.size() << endl;return 0;
}