参考:《算法导论》第16章
贪心算法:在对问题求解时,总是做出在当前看来是最好的选择。
贪心算法的基本思路:
1.建立数学模型来描述问题。
2.把求解的问题分成若干个子问题。
3.对每一子问题求解,得到子问题的局部最优解。
4.把子问题的解局部最优解合成原来解问题的一个解。
活动选择问题:贪心算法最经典的例子:给出n个任务和每个任务的开始和结束时间,找出可以完成的任务的最大数量,在同一时刻只能做一个任务。
先把活动按照结束时间的单调递增顺序排序,最早结束的活动总是最优解的一部分。
#include
using namespace std;
void GreedyChoose(int len,int *s,int *f,bool *flag)
{
flag[0] = true;
int j = 0;
for(int i=1;i= f[j]) //前一个活动的结束时间早于后一个活动的开始时间
{
flag[i] = true;
j = i;
}
}
}
int main()
{
int s[11] ={1,3,0,5,3,5,6,8,8,2,12}; //开始时间
int f[11] ={4,5,6,7,8,9,10,11,12,13,14}; //结束时间
bool mark[11] = {false}; //标记
GreedyChoose(11,s,f,mark); //贪心算法
for(int i=0;i<11;i++) //输出结果
if(mark[i])
cout<
线段覆盖:在一维空间中告诉你N条线段的起始坐标与终止坐标,要求求出这些线段一共覆盖了多大的长度。
#include
using namespace std;
int main()
{
int s[10] = {2,3,4,5,6,7,8,9,10,11};
int f[10] = {3,5,7,6,9,8,12,10,13,15};
int TotalLength = (3-2);
for(int i=1,j=0; i<10 ; ++i)
{
if(s[i] >= f[j])
{
TotalLength += (f[i]-s[i]);
j = i;
}
else
{
if(f[i] <= f[j])
continue;
else
{
TotalLength += f[i] - f[j];
j = i;
}
}
}
cout<