区间选点问题-贪心-C++

问题:

给定 𝑁 个闭区间 [ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。

输出选择的点的最小数量。

位于区间端点上的点也算作区间内。

输入格式

第一行包含整数 𝑁,表示区间数。

接下来 𝑁 行,每行包含两个整数 𝑎𝑖,𝑏𝑖,表示一个区间的两个端点。

输出格式

输出一个整数,表示所需的点的最小数量。

数据范围

1≤N≤10^5,
−10^9≤𝑎𝑖≤𝑏𝑖≤10^9

输入样例:
3
-1 1
2 4
3 5

代码:

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;
using Pii = pair<int, int>;
const int N = 100010;
Pii Range[N];
int main(){
  int n;
  cin >> n;
  for (int i = 0; i < n;i++){
    cin >> Range[i].first >> Range[i].second;
  }
  sort(Range, Range + n, [](const Pii &a, const Pii &b) -> bool
       { return a.second < b.second; });
  int ed = -2e9, res = 0;
  for (int i = 0; i < n;i++){
    if(Range[i].first>ed){
      res++;
      ed = Range[i].second;
    }
  }
  cout << res << endl;
}

题解:
题意就是给你10^5以下个区间,所以我们const int N = 100010;让你在数轴上选择一些点,这些点要能覆盖得到所有的区间,当然了,数量越少越好:

以此图为例子,灰色笔画的这两个点就是答案,你再也不可能找到更少的点来覆盖每个区间了。

计算机并不容易比我们更容易地判断出结果,我们可以先排个序看看:
我们暂且以每个区间的右端点的由小而大来排序,我们如果以每个区间的右端点来设点,其实更有可能让这个点覆盖到下一个区间甚至下下一个区间,这样更可能满足要求,这是贪心的思想,即:短视地选择我们遍历的区间的右端点作为答案,然后妄想让它尽可能地覆盖下一个、下下一个点......

我们还发现:如果A区间的右端点在下一个区间(记为B)的左端点之右的话,那么我们把A区间的右端点放到答案中,它不仅可以覆盖A区间,连B区间都覆盖了,甚至满足条件它连C区间也可以给覆盖了......我们只需维护一个变量ed记为我们刚埋的点,刚开始这个ed我们赋值为负无穷,

遇到一个区间,如果它的左端点比ed还小,那说明不用管它了,ed完全可以覆盖它,否则,说明这一个区间我们ed够不着,需要在这个区间设点了,即把这个区间的右端点作为新的ed,让他去在遍历下一个区间时,看能不能不设点,ed就能覆盖下一个区间。

总之,遇到区间问题,尽量想到排序,贪心.....

参考链接:链接

相关推荐
Dream it possible!12 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉12 小时前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生12 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴12 小时前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
Leuanghing12 小时前
【Leetcode】11. 盛最多水的容器
python·算法·leetcode
qy发大财12 小时前
加油站(力扣134)
算法·leetcode·职场和发展
qy发大财12 小时前
柠檬水找零(力扣860)
算法·leetcode·职场和发展
不想编程小谭17 小时前
力扣LeetCode: 2506 统计相似字符串对的数目
c++·算法·leetcode
01_18 小时前
力扣hot100——LRU缓存(面试高频考题)
leetcode·缓存·面试·lru
_Itachi__20 小时前
LeetCode 热题 100 73. 矩阵置零
算法·leetcode·矩阵