一、贪心算法
解决最优化问题的算法一般包含一系列的步骤,每一步都有若干的选择。对于很多最优化问题,只需要采用简单的贪心算法就可以解决,而不需要采用动态规划方法。贪心算法使所做的局部选择看起来都是当前最佳的,通过局部的最优化选择来产生全局最优解。本文将介绍贪心算法的理论基础和一些简单应用。在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法。
设计贪心算法的步骤:
将最优化问题转化为这样一个问题,即先做出选择,再解决剩下的一个子问题。
证明原问题的最优解之一可以由贪心选择得到。
证明在做出贪心选择后,将剩余的子问题的最优解和我们所做的贪心选择组合起来,可以得到原问题的一个最优解。
一般,如果我们能证明一个问题具有以下两个关键的性质,那么就可以设计出它的一个贪心算法。
(1)贪心选择性质:一个全局最优解可以通过局部最优解(贪心)选择来达到。即,当考虑做选择时,只考虑对当前问题最佳的选择而不考虑子问题的结果。而在动态规划中,每一步都要做出选择,这些选择依赖于子问题的解。动态规划一般是自底向上,从小问题到大问题。贪心算法通常是自上而下,一个一个地做贪心选择,不断地将给定的问题实例规约为更小的子问题。
(2)含有最优子结构: 如果问题的一个最优解包含了其子问题的最优解,则称该问题具有最优子结构。**
利用贪心解决问题的关键需要考虑如何选取贪心标准。
贪心算法的理论基础
关于贪心算法有一种理论可用于确定在何时使用贪心算法能给出最优解,虽然这种理论并没有包含贪心算法所适用的所有情况,但确实描述了许多非常有意义的情况。
二、适用题型
1.活动选择问题。
这层楼沿着走廊南北向的两边各有200个房间。最近,公司要做一次装修,需要在各个办公室之间搬运办公桌。由于走廊狭窄,办公桌都很大,走廊里一次只能通过一张办公桌。必须制定计划提高搬运效率。经理制定如下计划:一张办公桌从一个房间移到另一个房间最多用十分钟。当从房间i移动一张办公桌到房间j,两个办公室之间的走廊都会被占用。所以,每10分钟内,只要不是同一段走廊,都可以在房间之间移动办公桌。
思路如果搬运桌子的路径有重叠,那么必定不能够同时进行,所以考虑每个房间经过的次数即为搬运的最短情况。
int i, j;
int move[200];
int N; //搬运次数
//每次搬运的起点和终点
int from, to;
scanf("%d", &N);
memset(move, 0, sizeof(move));
for(i = 0; i < N; i++)
{
scanf("%d%d", &from, &to);
//将房间号映射为走廊号
from = (from - 1)/2;
to = (to - 1)/2;
//确保from<to,C++使用:swap(from, to)
if(from > to) {
int temp = from;
from = to;
to = temp;
}
//占用走廊情况
for(j = from; j <= to; j++)
move[j]++;
}