贪心算法 之 最多区间调度问题

问题主题:区间调度问题

问题描述:

有n项工作,每项工作分别在si开始,ti结束。对每项工作,你都可以选择参加或不参加,但选择了参加某项工作就必须至始至终参加全程参与,即参与工作的时间段不能有重叠(即使开始的时间和结束的时间重叠都不行)。

限制条件:

1<=n<=100000

1<=si<=ti,=109

样例:

输入

n=5

s={1,2,4,6,8}

T={3,5,7,9,10}

输出

3(选择工作1, 3, 5)

下面有几种最容易想到的贪心策略:

  • 在可选的工作(也就是和目前已选的工作都不重叠的工作)中,每次选取开始时间最早的工作。
  • 在可选的工作,每次都选取结束时间最早的工作。
  • 在可选的工作,每次选取最短的工作。
  • 在可选的工作,每次选取与最少可选工作重叠的工作。

其中,第二个贪心策略是正确的。

其余的在白书上 都是有反例的。

证明:

显然,该算法最后选出的区间不互相重叠,下面证明所选出区间的数量是最多的。设fi为该算法所接受的第i个区间的右端点坐标,gi为某最优解中的第i个区间的右端点坐标。

命题1.1  当i>=1时,该算法所接受的第i个区间的右端点坐标fi<=某最优解中的第i个区间的右端点坐标gi

该命题可以运用数学归纳法来证明。对于i=1,命题显然为真,因为算法第一个选择的区间拥有最小右端点坐标。令i>1,假定论断对i-1为真,即f_{i - 1} <= g_{i - 1}。则最优解的第i个可选区间所组成的集合包含于执行该算法时第i个可选区间所组成的集合;而当算法选择第i个区间时,选的是在可选区间中右端点坐标最小的一个,所以有f_{i} <= g_{i}。证毕。

设该算法选出了k个区间,而最优解选出了m个区间。

命题1.2  最优解选出的区间数量m=该算法选出的区间数量k

假设m>k,根据命题1.1,有f_{k} <= g_{k}。由于m>k,必然存在某区间,在gk之后开始,故也在fk之后开始。而该算法一定不会在选了第k个区间后停止,还会选择更多的区间,产生矛盾。所以m<=k,又因为m是最优解选出区间个数,所以m=k。

综上所述,算法选出的区间是最优解。

代码赘述.  将工作按照结束时间由大到小排序,每一次都保存最后一个工作的结束时间 t ,然后判断下一个工作的开始时间与 t 的大小,再确定是否能够选择。

猜你喜欢

转载自blog.csdn.net/no_O_ac/article/details/82389263