贪心问题的基本特征
- 可行解(可能有多个)
- 约束条件(可行解必须满足的条件)
- 目标函数(衡量可行解优劣)
- 最优解(使目标函数取得极值的可行解)
贪心算法的基本思想
每一步都按照由目标函数选取的的最优办法来进行,即每一次操作的都应使得目标函数在当前情况下尽可能地大。这种算法只考虑眼前情况,不考虑后果。这一特点决定了贪心算法必须具有无后效性,即某个状态的选择不会影响到之前的状态,只与当前状态有关。
解决贪心问题的一般流程
- 分析问题,得出约束条件和目标函数
- 分解问题,把问题分解成多个子问题
- 对子问题求最优解
- 合成所有子问题的最优解,得到最终解
*贪心和DP其实很像,都是将问题分解成许多易于解决的子问题,再求子问题的最优解。
事实上,我们可以把贪心算法当成DP的一个特例。
首先把所有的子问题看成一棵树,树顶就是原问题。通常来讲,DP问题都是自底向上构造问题的解,把每一个节点遍历一遍(也就是对于一个子树的跟,把每个叶子节点都求出解,并选出最优解作为自己的值),而贪心问题则可以通过数学方法证明:任意一个子问题的最优解(子树根的值)与其叶子节点的值(最小子问题的解)无关,也就是说不需要遍历就可以求出节点的值。
既然不需要遍历树,那也就不用自底向上求解了,直接从根开始,每次选择最优的路一直向下走就可以解决问题。
例题
描述
Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d.
We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates.
Figure A Sample Input of Radar Installations
输入
The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases.
The input is terminated by a line containing pair of zeros
输出
For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. “-1” installation means no solution for that case.
样例输入
3 2
1 2
-3 1
2 1
1 2
0 2
0 0
样例输出
Case 1: 2
Case 2: 1
题目大意:
x轴是海岸线,x轴上方是海洋。海洋中有n(1<=n<=1000)个岛屿,可以看作点。
给定每个岛屿的坐标(x,y),x,y 都是整数。当一个雷达到岛屿的距离 不超过d,则认为该雷达覆盖了该岛屿。
雷达只能放在x轴上。问至少需要多少个雷达才可以覆盖全部岛屿。
思路:
对于每个岛屿,若要覆盖它,则雷达必须在x轴上[s,e]的范围内。换言之,如果雷达在[s,e]范围内,则一定可以覆盖相应的岛屿。
这是一个贪心问题,我们按照贪心问题的方法来分析一下
- 约束条件:雷达在区间[s,e]内
- 目标函数:设radar为雷达的坐标,F(radar)=包含有radar的集合数
- 子问题就是对一个雷达求解F(radar)>0,最优解就是F(radar)取最大值时,radar的坐标
那么如何求子问题的最优解呢?
想到如果有一个雷达同时覆盖多个区间,那么把这多个区间按起点坐标从小到大排序,则如果把雷达装在最后一个区间k的起点,就能覆盖所有区间。
接下来用反证法证明一下(大多贪心算法的证明部分都使用反证法)
证明:
如果它不能覆盖某个区间x,那么它必然位于 1. x起点的左边 2. x终点的右边。
情况1) 和k 的起点是最靠右的矛盾
情况2) 如果发生情况2,则不可能找到一个点同时覆盖x和k(即x区间和k区间没有交集),也和前提矛盾
AC代码请参考博客 > > > https://blog.youkuaiyun.com/deepmindman/article/details/52278572 < < <