AcWing 905. 区间选点 (AcWing 908. 最大不相交区间数量) 题解 贪心

题目

AcWing 905. 区间选点 (AcWing 908. 最大不相交区间数量) 题解 贪心_第1张图片


思路

碰到区间之类的问题,贪心的思路都是先按某种性质排序,再利用某种性质再遍历判断
AcWing 905. 区间选点 (AcWing 908. 最大不相交区间数量) 题解 贪心_第2张图片

  • 先将每个区间按右端点从小到大排序
  • 再从前往后依次枚举每个区间
    1.如果当前区间中已经包含点,则直接pass
    2.否则,选择当前区间的右端点
    为什么要选择右端点?因为(区间已经按照右端点排序)选择右端点,最有可能一个点覆盖多个区间
    其实每次选中的点,都是区间的右端点
    AcWing 905. 区间选点 (AcWing 908. 最大不相交区间数量) 题解 贪心_第3张图片
    时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn) (主要在排序上)

代码

#include
#include
using namespace std;
const int N=1e5+10;
struct range
{
    int l,r;
    bool operator<(const range &w)const   //重载一下小于号,便于对区间右端点排序
    {
        return r<w.r;
    }
}range[N];
int n,a,b;
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%d%d",&a,&b);
        range[i]={a,b};
    }
    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;
        }
    }
    printf("%d",res);
    return 0;
}

变题

题目

AcWing 905. 区间选点 (AcWing 908. 最大不相交区间数量) 题解 贪心_第4张图片
本题和上题,代码可以互通,完全不用改,只是res的含义不同
本题中的res表示的是不相交区间的数量,上题中的res表示的是选择的点的数量
上题是在枚举排序后的每个区间的同时,找到了不相交区间集合,而每次只选择右端点,保证右端点将他们覆盖。

证明

AcWing 905. 区间选点 (AcWing 908. 最大不相交区间数量) 题解 贪心_第5张图片


总结

这类题型其实都是在求最大不重叠区间的个数
都是一个思路
区间选点,求最少个点覆盖最多个区间,其实也就是求最大不重叠的区间有多少个,这些区间是必须得至少放一个点的。


你可能感兴趣的:(#,基础算法模板总结,code,刷题,总结&记录,贪心算法,c++,算法,区间问题)