所谓“贪心算法”是指:在对问题求解时,总是作出在当前看来是最好的选择。也就是说,不从整体上加以考虑,它所作出的仅仅是在某种意义上的局部最优解(是否是全局最优,需要证明)。在对问题求解时,总是作出在当前看来是最好的选择。也就是说,不从整体上加以考虑,它所作出的仅仅是在某种意义上的局部最优解(是否是全局最优,需要证明)。
特别说明:若要用贪心算法求解某问题的整体最优解,必须首先证明贪心思想在该问题的应用结果就是最优解!!
用事实说话——实 例 分 析
一、事件序列问题
已知N个事件的发生时刻和结束时刻(见下表,表中事件已按结束时刻升序排序)。一些在时间上没有重叠的事件,可以构成一个事件序列,如事件
{2,8,10}。事件序列包含的事件数目,称为该事件序列的长度。请编程找出一个最长的事件序列。
事件编号 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
发生时刻 |
1 |
3 |
0 |
3 |
2 |
5 |
6 |
4 |
10 |
8 |
15 |
15 |
结束时刻 |
3 |
4 |
7 |
8 |
9 |
10 |
12 |
14 |
15 |
18 |
19 |
20 |
Begin[a1]<End[a1]<=…<=Begin[an]<End[an]。
可以证明,如果在可能的事件a1<a2<…<an中选取在时间上不重叠的最长序列,那么一定存在一个包含a1(结束最早)的最长序列。
二、区间覆盖问题
用i来表示x轴上坐标为[i-1,i]的区间(长度为1),并给出M(1=<M=<200)个不同的整数,表示M个这样的区间。现在让你画几条线段覆盖住所有的区间,条件是:每条线段可以任意长,但是要求所画线段之和最小,并且线段的数目不超过N(1=<N=<50)。
例如:M=5个整数1、3、4、8和11表示区间,要求所用线段不超过N=3条
0 1 2 3 4 5 6 7 8 9 10 11
算法分析:3 4 10 20 30 40 50 60 70 80 2 1 3 2 200 3 10 100 20 80 30 50
10 20 30算法分析:1、如果没有交叉,总时间应该是多少?
2、影响搬运时间的因素是什么?
3、如果每趟处理都包含最大重叠,处理后 的效果是什么?
4、得出什么结论?
·
#include <iostream>
using namespace std;
int main()
{ intt,i,j,N,P[200];
ints,d,temp,k,min;
cin>>t;
for(i=0;i<t;i++)
{
for(j=0;j<200;j++)
P[j]=0;
cin>>N;
for(j=0;j<N;j++)
{
cin>>s>>d;
s=(s-1)/2;
d=(d-1)/2;if(s>d)
{ temp=s;
s=d;
d=temp; }
for(k=s;k<=d;k++)
P[k]++;
}
min=-1;
for(j=0;j<200;j++)
if(P[j]>min)
min=P[j];
cout<<min*10<<endl;
}
return 0;
}1、从问题的某个初始解出发。
2、采用循环语句,当可以向求解目标前进一步时,就根据局部最优策略,得到一个部分解,缩小问题的范围或规模。
3、将所有部分解综合起来,得到问题的最终解。
到此结束,see you next time!!
原文:http://blog.csdn.net/u011292087/article/details/19401359