相容问题——贪心法

1、问题

有n项活动申请使用同一个礼堂,每项活动有一个开始时间和一个截止时间。如果任何两个活动不能同时举行,问如何选择这些活动,从而使得被安排的活动数量达到最多。
设S={1,2,…,n}为活动的集合,si和fi分别为活动i的开始和截止时间,i=1,2,…,n
定义:活动i和j相容<==>si≥fj或sj≥fi,i≠j
求S最大的两两相容的活动子集A。

2、解析

方法一:按照截止时间从小到大排序
把活动按照截止时间从小到大排序,使得f1<=f2<=…<=fn ,然后从前向后挑选,只要与前面选的活动相容,就可以把项活动选入 A。
在这里插入图片描述
k=3
(1) 选择活动1:截止时间最早:活动2、3与活动1不相容,活动4与活动1相容;
(2) 选择活动4:活动5、6、7与活动4不相容,活动8与活动4相容;
(3) 选择活动8:活动9、10与活动8不相容。
证明对于任意正整数k,算法的前k步选择都能导致一个最优解。
定理:算法执行到第k步,选择k项活动,那么存在最优解A包含i1=1,i2,….,ik

证明(数学归纳法):将S中的活动按照截止时间递增顺序排列。
(1) k=1时,算法选择了活动 1.(算法执行到第一步,选择结束时间最短的活动作为第一个活动)
设A={i1,i2,…,ij}是问题的一个最优解,
·如果i1=1,那么存在最优解包含了活动1,得证
·如果i1≠1,那么用1替换i1得到AA=(A-{i1}∪{1}

A’和A的活动个数相等,活动1比i1结束得更早,因此活动1和i2,…,ij等活动也相容,于是A’也是问题的一个最优解,因此存在最优解包含了活动1.得证。

A={i1,i2,…,ij}
A`={1,i2,…,ij}
f1<fi1<si2→f1<si2→1和i2相容

(2) 假设对于任意正整数k,命题正确。
令i1=1,i2,…,ik是算法前k步顺序选择的活动,根据归纳假设,一个规模为n的问题的最优解,当算法步骤为k时,i1=1,i2,…,ik为前k个最优解:

1)构建问题最优解A:由归纳假设,问题S存在一个最优解A由前k个和S中剩下活动中选出部分,即A={i1,i2,…,ik}∪B,
其中 B 必然是 S 中剩下活动中与i1,i2,…,ik相容的活动Sb(令Sb是 S 中剩下活动中与i1,i2,…,ik相容的活动)的最优解。

证明(反证法):如果 B 不是Sb的最优解,必然存在 B’是Sb的最优解, 即|B’|>|B|,则A={i1,i2,…,ik}∪B’将比 A 的活动更多,与A是最优解矛盾。因此,B 是Sb的最优解。
2)分离最优解B的一个最早结束任务:由(1)得算法第一步选择结束 时间最早的活动总是导致一个最优解。对于子问题Sb存在一个包含选择结束时间最早的活动ik+1的最优解B*={ik+1,….},B和 B 都是最优解,于是
A={i1=1,i2,…,ik}∪B={i1=1,i2,…,ik}∪B={i1=1,i2,…,ik,ik+1}∪(B*-{ik+1})包含前k+1的活动,得证。

方法二:按开始时间从小到大排序
在这里插入图片描述
方法三:按占用时间排序
在这里插入图片描述

3、设计

    cin>> n;
	for(i=1;i<=n;i++)
	 cin >>a[i].l >>a[i].r;
	sort(a+1,a+1+n);
	int res=1;
	for(i=1,j=2;j<=n;j++){
		if(a[i].r<=a[j].l){
			res++;
			i=j;
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值