海边拾贝,沧海一粟

一个ACMer的博客-我不是喜欢ACM,我只是贪恋AC

区间问题与贪心算法

区间问题与贪心算法

(1)区间完全覆盖问题

问题描述: 给定一个长度为m的区间,再给出n条线段的起点和终点(注意这里是闭区间), 求最少使用多少条线段可以将整个区间完全覆盖 样例:
区间长度8,可选的覆盖线段[2,6],[1,4],[3,6],[3,7],[6,8],[2,4],[3,5] 解题过程:
1、将每一个区间按照左端点递增顺序排列,排完序后为[1,4],[2,4],[2,6],[3,5], [3,6],[3,7],[6,8]
2、设置一个变量表示已经覆盖到的区域。再剩下的线段中找出所有左端点小于等于当前
已经覆盖到的区域的右端点的线段中,右端点最大的线段在加入,直到已经覆盖全部的区域 3、过程:
假设第一步加入[1,4],那么下一步能够选择的有[2,6],[3,5],[3,6],[3,7],
由于7最大,所以下一步选择[3,7],最后一步只能选择[6,8],这个时候刚好 达到了8退出,所选区间为3 4、贪心证明:
需要最少的线段进行覆盖,那么选取的线段必然要尽量长,而已经覆盖到的区域之前
的地方已经无所谓了,(可以理解成所有的可以覆盖的左端点都是已经覆盖到的地方),
那么真正能够使得线段更成的是右端点,左端点没有太大的意义,所以选择右端点来覆盖

(2)最大不相交覆盖

(我总感觉这个算法不对,这不应该和会议安排问题一样吗? 直接按照终点排序再依次选择???) 问题描述:
给定一个长度为m的区间,再给出n条线段的起点和终点(开区间和闭区间处理的方法是
不同,这里以开区间为例),问题是从中选取尽量多的线段,使得每个线段都是独立的, 就是不和其它有任何线段有相交的地方 样例:
区间长度8,可选的覆盖线段[2,6],[1,4],[3,6],[3,7],[6,8],[2,4],[3,5] 解题过程:
对线段的右端点进行升序排序,每加入一个线段,然后选择后面若干个 (也有可能是一个)右端点相同的线段,选择左端点最大的那一条,如果加入以后不会
跟之前的线段产生公共部分,那么就加入,否则就继续判断后面的线段
1、排序:将每一个区间按右端点进行递增顺序排列,拍完序后为[1,4],[2,4],[3,5],[2,6],
[3,6],[3,7],[6,8] 2、第一步选取[2,4],发现后面只能加入[6,8],所以区间的个数为2
3、贪心证明:因为需要尽量多的独立的线段,所以每个线段都尽可能的小,
对于同一右端点,左端点越大,线段长度越小。那么为什么要对右端点进行排序呢?
如果左端点进行排序,那么右端点是多少并不知道,那么每一条线段都不能对之前所有 的线段进行一个总结,那么这就明显不满足贪心的最有子结构了。

(3)区间选点问题

问题描述: 给定一个长度为m的区间,再给出n条线段和这n条线段需要满足的要求
(要求是这n条线段上至少有的被选择的点的个数),问题是整个区间内最少 选择几个点,使其满足每一条线段的要求. 样例:略 解题过程:
将每个线段按照终点坐标进行递增排序,相同终点的前点坐标从大到小排列, 一个个将其满足(每次选择的点为该条线段的右端点) 贪心证明:
要想使得剩下的线段上选择的点最少,那么就应该尽量使得已经选择了的点尽量能
在后面的线段中发挥作用,而我们是从左往右选择线段的,那么要使得选取的点能
满足后面线段的要求,那么必须是从线段的右端点开始选点,那么问题(2)一样涉及
到一个问题,如果是按照线段的左端点对线段进行排序的话,不知道右端点的话,
每一条线段都不能对之前已经操作过的所有线段进行一个总结,那么这就同样不满足 贪心算法的最优子结构性质了。
可以解决的实际问题:数轴上面有n个闭区间[a,b],取尽量少的点,使得每个区间内都 至少有一个点(不同区间内含的点可以是同一个)

D - Radar Installation

例题 应用例题:(貌似不是很简单。。。)   有一列整数,他的每一个数各不相同,我们不知道有多少个,但我们知道在
某些区间中至少有多少个整数,用区间(L,R,C)来描述,表示整数序列 中至少有C个整数来自子区间[L,
R],若干个这样的区间,问这个整数序列的长 度最少能为多少。

阅读更多
版权声明:本文为博主原创文章,可随意转载 https://blog.csdn.net/weixin_38686780/article/details/79960811
文章标签: 区间问题
个人分类: 贪心
上一篇ZOJ Problem Set - 4020 Traffic Light
下一篇c++中处理2进制的一些函数
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭