区间贪心:最小区间覆盖问题、PIPI的高速公路
区间贪心:最小区间覆盖问题、PIPI的高速公路
文章目录
- 区间贪心:最小区间覆盖问题、PIPI的高速公路
- 问题1:
- 思路:
- 代码:
- 问题2:
- 思路:
- 代码:
问题1:
思路:
本题是区间贪心的一种:在满足覆盖[L,R]区间的情况下,最少能选择多少个区间
我们可以将线段(区间)按左端点从小到大排序,我们的贪心策略是每次所选择的区间使后面预留的空间最小,即尽可能多地占用[L,R]中的空间。为此,我们可以定义右极限rLimit,表示当前所遍历到的合法区间中r的最大值,初始化为L,每次我们从合法的备选区间(即l <= rLimit
)中找出右端点r最大的区间并选择该区间,接着更新rLimit,使rLimit = r
,持续该过程,直到rLimit >= R,我们便用最少的区间数覆盖了[L,R]
代码:
import java.util.*;public class Main {static List<Region> array = new ArrayList<>();public static void main(String[] args) {int i, n, L, R, li, ri, ans, rLimit, rMax;boolean flag;Scanner scanner = new Scanner(System.in);while (scanner.hasNextInt()) {ans = 0;array.clear();n = scanner.nextInt();L = scanner.nextInt();R = scanner.nextInt();for (i = 0;i < n;i++) {li = scanner.nextInt();ri = scanner.nextInt();if (ri < L || li > R) {continue;}array.add(new Region(li, ri));}if (array.size() == 0) {System.out.println(-1);continue;}Collections.sort(array, new Comparator<Region>() {@Overridepublic int compare(Region o1, Region o2) {return o1.l - o2.l;}});rLimit = L;rMax = L;for (i = 0;i < array.size();i++) {flag = false;while (i < array.size() && array.get(i).l <= rLimit) {rMax = Math.max(rMax, array.get(i).r);i++;flag = true;}if (flag) {i--;rLimit = rMax;ans++;}if (rLimit >= R) {break;}}System.out.println(rLimit >= R ? (ans == 0 ? -1 : ans) : -1);}}}class Region {public int l;public int r;public Region(int l, int r) {this.l = l;this.r = r;}
}
问题2:
思路:
该题乍一看好像和区间没什么关系,但我们需要发现对于每个村庄(x,y),到其距离不超过D的出口的x坐标值处于一个区间内,该区间为[x - sqrt(d ^ 2 - y ^ 2),x + sqrt(d ^ 2 - y ^ 2)
。
于是,这道题被转化为了区间贪心的问题。成为了区间贪心的一种:在满足每个区间中至少有一个点(出口)情况下,最少能选择多少个点(出口)?我们的贪心策略是使一个点(出口)尽可能多地处于不同区间内,即尽可能多的区间能共用一个点(出口)。
如何执行上述贪心策略呢?我们可以按区间的右端点从小到大对区间排序,定义右极限rLimit,初值为第一个区间的右端点,然后进行区间的遍历。若当前遍历到的区间的左端点<=rLimit,说明当前区间可以和前面的某些区间共用一个点(这是因为当前区间和前面的某些区间都满足左端点<=rLimit,且由于排序关系,右端点>=rLimit,也就是说这些区间存在公共的重叠部分,可以共用一个出口),若当前遍历的区间左端点>rLimit,说明当前区间和前面的区间不可共用一个点,所需出口数ans++,并更新rLimit的值为当前区间的右端点,重复上述过程直到遍历完所有区间。
代码:
import java.util.*;public class Main {static Region[] array = new Region[1002];public static void main(String[] args) {int ans, i, n;double l, d, x, y, left, right, nextLeft, nextRight;Scanner scanner = new Scanner(System.in);while (scanner.hasNextDouble()) {ans = 0;l = scanner.nextDouble();d = scanner.nextDouble();n = scanner.nextInt();for (i = 0;i < n;i++) {x = scanner.nextDouble();y = scanner.nextDouble();left = x - Math.sqrt(d * d - y * y);right = x + Math.sqrt(d * d - y * y);left = left > 0 ? left : 0;right = right > l ? l : right;array[i] = new Region(left, right);}Arrays.sort(array, 0, n, new Comparator<Region>() {@Overridepublic int compare(Region o1, Region o2) {if (o1.right - o2.right > 0) {return 1;}return -1;}});right = array[0].right;for (i = 0;i < n;i++) {nextLeft = array[i].left;nextRight = array[i].right;if (nextLeft > right) {right = nextRight;ans++;}}ans = n == 0 ? ans : ans + 1;System.out.println(ans);}}
}class Region {public double left;public double right;public Region(double left, double right) {this.left = left;this.right = right;}
}
区间贪心:最小区间覆盖问题、PIPI的高速公路相关推荐
- 632. Smallest Range Covering Elements from K Lists 最小区间
你有 k 个升序排列的整数数组.找到一个最小区间,使得 k 个列表中的每个列表至少有一个数包含在其中. 我们定义如果 b-a < d-c 或者在 b-a == d-c 时 a < c,则区 ...
- [Leetcode][第632题][JAVA][最小区间][堆][滑动窗口]
[问题描述][困难] [解答思路] 1. 堆 复杂度 class Solution {public int[] smallestRange(List<List<Integer>> ...
- NYOJ-14 会场安排问题(经典贪心,区间完全不覆盖模板)
附另一:此类问题选题总结:https://blog.csdn.net/qq_41289920/article/details/81001357 题干: 会场安排问题 时间限制:3000 ms | 内存 ...
- 贪心法——区间覆盖问题
贪心法--区间覆盖问题 区间覆盖问题.数轴上有n个闭区间[ai,bi][a_i, b_i],选择尽量少的区间覆盖一条指定线段[s,t][s,t]. 先进行预处理,将不包含[s,t][s,t]的区间都去 ...
- UVa 10020 (最小区间覆盖) Minimal coverage
题意: 数轴上有n个闭区间[ai, bi],选择尽量少的区间覆盖一条指定线段[0, m] 算法: [start, end]为已经覆盖到的区间 这是一道贪心 把各个区间先按照左端点从小到大排序,更新st ...
- 一份贪心算法区间调度问题解法攻略,拿走不谢
作者 | labuladong 来源 | labuladong(ID:labuladong) [导读]什么是贪心算法呢?贪心算法可以认为是动态规划算法的一个特例,相比动态规划,使用贪心算法需要满足更多 ...
- matlab车辆贪心作业调度,贪心算法-区间调度-Interval Scheduling
什么是贪心算法呢? 贪心算法可以认为是动态规划算法的一个特例,相比动态规划,使用贪心算法需要满足更多的条件(贪心选择性质),但是效率比动态规划要高. 比如说一个算法问题使用暴力解法需要指数级时间,如果 ...
- (贪心)区间问题大致思路
1.选择不相交区间. a.描述: 数轴上有n个开区间(ai, bi).选择尽量多个区间,使得这些区间两两 没有公共点. b.思路总结: 1.区间x完全包含y,选y 2.按照bi从小到大排序,从第一个区 ...
- 贪心算法—区间调度 电影节(POJ 4151)
贪心算法--区间选取问题 或是区间调度问题 本文解决一个很经典的贪心算法问题 Interval Scheduling(区间调度问题).给你很多形如[start,end]的闭区间,请你设计一个算法,算出 ...
- 贪心算法——区间选点问题
转载:https://blog.csdn.net/xia842655187/article/details/51944763 区间选点的问题大致可以描述为: 给定N个区间[a,b],取尽量少的点,使 ...
最新文章
- mysql mgr应用场景_悄悄告诉你 MySQL MGR 牛在哪?
- xgboost lightgbm catboost 多分类 多标签
- 微型计算机中常用的进位计数制有,计算机试题与答案
- poj 3378 Crazy Thairs
- android android:process=,Android app启动流程
- c语言float m1 m2什么意思,m1和m2的区别,一文带你秒懂这两者的关联
- 第19章,运维自动化之系统安装
- php.exe占用资源过大,记录一次php占用系统资源过高的问题
- EJB3.0学习笔记---MDB--第一个MDBBean程序:
- 信道与信道容量(一)
- Android系统epub阅读器分享
- 由“官方通知”论语音合成,一键合成你想要的语音
- 如何对pdf电子文档进行手写签名
- web实验报告——JSP动态网页编程
- 微服务A读配置中心报Could not locate PropertySource错误
- STM32CubeIDE STM32H743实现软件触发ADC实现多通道DMA方式、过采样方式采集数据
- PTA寒假基础题训练(含解题思路)(中)
- 斑马打印机的安装调试,生成PDF
- iCabMobile更新后,Installous的Downloads不能用的解决方法
- 滑动窗口类型(Sliding window)