acwing 区间选点-java-贪心

本文详细介绍了贪心算法在解决区间问题中的应用,特别是针对区间选点问题。通过排序和枚举策略,找到覆盖所有区间所需的最少点数。题目要求在数轴上选择尽量少的点,使得每个区间内至少包含一个点,文章提供了具体的解题思路和Java代码实现,证明了贪心算法在单峰情况下的有效性。
摘要由CSDN通过智能技术生成

贪心算法

选择当前最好的情况走过去 (短视) 每次选择局部最优解 然后最后走到全局最优解 但是只能是单峰的情况下,才可以使用贪心 。 多峰的情况下 就通过这个够呛找到全局最优解。

两种模板(区间选点,最大不相交区间数)按照右端点排序,两种模板(区间覆盖,区间分组)按照左端点排序。

一、区间选点

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

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

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

输入格式
第一行包含整数 N,表示区间数。

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

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

数据范围
1≤N≤105,
−109≤ai≤bi≤109
输入样例:
3
-1 1
2 4
3 5
输出样例:
2

1.题解-时间复杂度 O(nlogn)

题目理解

题目的理解
1、一般区间问题都会排序 我们都会按照区间右端点排序 从小到大排序
题解2

2、从前往后依次枚举每个区间 都枚举区间的右端点end 初始化是无穷小 分情况讨论: 如果当前区间中已经包含点,则直接pass , else 选择当前区间的右端点

此题的最优解就是所有解决方案中的最小值
ans <= cnt cnt表示一个可行解的点数
证明的话就是 A <= B B >= A -> A =B

证明:

(1)找到cnt个点,满足题意情况,则最优解Ans <= cnt
(2)找到cnt个点,即找到cnt个区间,区间内没有交集的话 ,则说明可能有区间没有被这cnt个点覆盖过,所以最优解Ans >= cnt
综上:Ans == cnt

代码如下(示例):

  import java.io.*;
import java.util.*;

public class Main {
    static final int N = (int)1e5 + 10;
    static int n;
    static Node[] range = new Node[N];
    static class Node {
        int l, r;
        public Node(int l, int r) {
            this.l = l;
            this.r = r;
        }
    }
    public static void main(String[] args) throws IOException {  
        BufferedReader put =new BufferedReader(new InputStreamReader(System.in));
      String arr = put.readLine();
       n = Integer.parseInt(arr);               
        int a, b;
        for (int i = 0; i < n; ++i) {
            String[] cur = put.readLine().split(" ");
            a = Integer.parseInt(cur[0]);
            b = Integer.parseInt(cur[1]);
            range[i] = new Node(a, b);
        }
        Arrays.sort(range, 0, n, (o1, o2) -> o1.r - o2.r);//按照右端点排序
        //这里面用的是数组排序  也可以用Collections 、 list 等  
        //但是排序l 用以上式子方便 或者这种   Collections.sort(list);
        int t = Integer.MIN_VALUE, cnt = 0;
        for (int i = 0; i < n; ++i) {
            if (range[i].l > t) {//如果当前点不能覆盖这个区间 就Pass  else就更新这个点 并且cnt+1
                t = range[i].r;//选择右端点
                ++cnt;
            }
        }
       System.out.println(cnt + " ");
        
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依嘫_吃代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值