算法-贪心

核心:局部最优->全局最优

例1:AcWing 905. 区间选点

思路:
1.将每一个区间右端点排序
2.枚举每一个区间,如果当前区间包含点,则之间pass,otherwise选择当前区间右端点

证明:
这里使用夹逼定理进行证明,后面的最大不相交区间和区间分组都是用的这个方式
Ans<=cnt证明:
因为Ans表示的是最优解,即所用点数最少;而cnt只是求出了一个合法解,合法解的点数必然小于等于最优解

Ams>=cnt证明:
根据y总当时的贪心策略,当前区间不包含点时我们会选择它的右端点作为最终解中的一个点,因为选择的是右端点且区间是按右端点从小到大排序的,所以当前不包含点的区间与上一个选了右端点的区间,两者之间必然不存在交集;由此,这cnt个选择了右端点作为最终解的区间彼此之间必然不存在交集,即所有区间中至少存在cnt个彼此不相交的区间;如此,要想让选出的点覆盖所有区间,至少需要选cnt个点,即任何一个方案都至少包含cnt个点,最优解也不例外;Ans>=cnt得证

代码:

#include <bits/stdc++.h>

using namespace std;

const int N=1e5+10,INF=-2e9;

struct hh
{
    int l,r;//左右端点
}a[N];

bool cmp(hh a,hh b)
{
    return a.r<b.r;
}

int n,cnt;

int main()
{
    cin>>n;
    for(int i=0;i<n;i++) cin>>a[i].l>>a[i].r;
    
    sort(a,a+n,cmp);//区间右端点排序
    
    int end=INF;//初始化
    for(int i=0;i<n;i++)//枚举区间
        if(a[i].l>end)
        {
            cnt++;
            end=a[i].r;//更新右端点
        }
    
    cout<<cnt<<endl;
    
    return 0;
}
posted @   Eric`  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示