【贪心】AcWing 803. 区间选点

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

905. 区间选点

文章目录

题目描述

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

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

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

输入格式

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

接下来 N 行每行包含两个整数 a i , b i a_i,b_i ai,bi表示一个区间的两个端点。

输出格式

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

数据范围

  • 1 ≤ N ≤ 1 0 5 1≤N≤10^5 1N105
  • − 1 0 9 ≤ a i ≤ b i ≤ 1 0 9 -10^9≤a_i≤b_i≤10^9 109aibi109

输入样例

3
-1 1
2 4
3 5

输出样例

2

方法贪心

解题思路

贪心算法是指在对问题求解时总是做出在当前看来是最好的选择。也就是说不从整体最优上加以考虑算法得到的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解关键是贪心策略的选择。

  1. 将所有区间按右端点从小到大排序
  2. 维护点设置为负无穷依次搜索每个区间
    如果新区间的左端点 > 维护点则将维护值更新成新区间的右端点
    如果新区间的右端点 <= 维护点则说明维护点也在这个新区间内。
    在这里插入图片描述

Tips

  • 这里保存区间的左右端点采用了 struct 类型按区间右端点进行排序需要对 struct 类型的数组自定义排序
//定义结构体
struct Type{
      int a;
      double b;
      //升序需要的操作符函数
      bool operator < (const Type& right) const 
      {
          return a < right.a;
      }//asscend
      //降序需要的操作符函数
      bool operator > (const Type& right) const
      {
          return a > right.a;
      }//descend
};

代码

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;
int n;

struct Range {
    int l, r;
    bool operator < (const Range &W) const {
        return r < W.r;
    };
}range[N];

int main() {
    cin >> n;
    for(int i = 0; i < n; i++) {
        int l, r;
        cin >> l >> r;
        range[i] = {l, r};
    }
    sort(range, range + n);
    int res = 0, ed = -2e9;
    for(int i = 0; i < n; i++) 
        if(range[i].l > ed) {
            res++;
            ed = range[i].r;
        }
    cout << res;
    return 0;
}

复杂度分析

  • 时间复杂度 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)
  • 空间复杂度 O ( n ) O(n) O(n)
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6