[贪心入门]活动安排问题

有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动?

分析: 我们就是想提高教室地利用率,尽可能多地安排活动。
考虑容易想到的几种贪心策略:

(1) 开始最早的活动优先,目标是想尽早结束活动,让出教室。
然而, 这个显然不行,因为最早的活动可能很长,影响我们进行后面的活动。例如活动开始和结束时间分别为[0, 100), [1,2) ,[2, 3), [3, 4),[4,5],安排[0,100)的这个活动之后,其他活动无法安排,可是最优解是安排除它外的4个活动。

(2) 短活动优先, 目标也是尽量空出教室。但是不难构造如下反例: [0,5) [5,10) [3, 7), 这里[3,7)最短,但如果我们安排了[3,7),其它两个无法安排了。但是最优解显然是安排其它两个,而放弃[3,7),可见这个贪心策略也是不行的。

(3) 最少冲突的活动优先, 既然上面安排活动是想减少冲突,那么如果我们优先安排冲突最少的活动可以么?至少从(1)和(2)看来,这个策略是有效的。真是对的么? 尝试这个例子:

[0,2) [2,4) [4,6) [6,8)
[1,3) [1,3) [1,3) [3,5) [5,7) [5,7) [5,7)

看一下[0,2) 和3个活动冲突——3个[1,3)

[2,4)和4个活动冲突3个[1,3)和一个[3,5)
[4,6)和也和4个活动冲突3个[5,7)和一个[3,5)
[6,8)和3个活动冲突——3个[5,7)

下面[1,3)和[5,7)每个都和5个活动冲突,
而[3,5)只和两个活动冲突——[2,4)和[4,6)。

那按照我们的策略应该先安排[3,5), 可是一旦选择了[3,5),我们最多只可能安排3个活动。
但明显第一行的4个活动都可以安排下来,所以这种策略也是不对的。

(4) 看似最不对的策略——结束时间越早的活动优先。这个策略是有效的,我们可以证明。假设最优解OPT中安排了m个活动,我们把这些活动也按照结束时间由小到大排序,显然是不冲突的。假设排好顺序后,这些活动是a(1) , a(2), a(3)….am

假设按照我们的贪心策略,选出的活动自然是按照结束时间排好顺序的,并且也都是不冲突的,这些活动是b(1), b(2) …b(n)

问题关键是,假设a(1) = b(1), a(2) = b(2)…. a(k) = b(k),但是a(k+1) != b(k+1),回答几个问题:

(1)b(k+1)会在a(k+2), a(k+3), …. a(m)中出现么?
不会。因为b(k+1)的结束时间是最早的,即f(b(k+1)) <= f(a(k+1)),而a(k+2), a(k+3), …. a(m)的开始时间和结束时间都在f(a(k+1))之后,所以b(k+1)不在其中。

(2)b(k+1)和a(1), a(2), …. a(k) 冲突么?
不冲突,因为a(1), a(2), …. a(k)就是b(1), b(2), …. b(k)

(3)b(k+1)和a(k+2), a(k+3), …. a(m)冲突么?
不冲突,因为f(b(k+1)) <= f(a(k+1)),而a(k+2), a(k+3), …. a(m)的开始时间都在f(a(k+1))之后,更在f(b(k+1))之后。

因此我们可以把a(k+1) 换成b(k+1), 从而最优解和我们贪心得到的解多了一个相同的,经过一个一个替换,我们可以把最优解完全替换成我们贪心策略得到的解。 从而证明了这个贪心策略的最优性。

最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。

输入

第1行:1个数N,线段的数量(2 <= N <= 10000)
第2 - N + 1行:每行2个数,线段的起点和终点(-10^9 <= S,E <= 10^9)

输出

输出最多可以选择的线段数量。

输入示例

3
1 5
2 3
3 6

输出示例

2
 1 n=int(input())
 2 a=[]
 3 for i in range(n):
 4     b=list(map(int,input().split()))
 5     a.append(b)
 6 a.sort(key=lambda i:i[1])
 7 ans=0
 8 last_e=-100000000000
 9 for i in a:
10     if last_e<=i[0]:
11         ans+=1
12         last_e=i[1]
13 print(ans)    
时间: 2024-10-05 09:23:15

[贪心入门]活动安排问题的相关文章

贪心入门——活动安排问题

贪心入门的几个例题来自51nod 问题描述 有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 输入 第1行:1个数N,线段的数量(2 <= N <= 10000) 第2 - N + 1行:每行2个数,线段的起点和终点(-10^9 <= S,E <= 10^9) 输出 输出最多可以选择的线段数量. 输入示例 3 1 5 2 3 3 6 输出示例 2 求解思路 按照活动的结束时间早的优先 算法代码 #include <

[贪心入门]活动安排问题之二

有若干个活动,第i个开始时间和结束时间是[Si,fi),活动之间不能交叠,要把活动都安排完,至少需要几个教室? 分析:能否按照之一问题的解法,每个教室安排尽可能多的活动,即按结束时间排序,再贪心选择不冲突的活动,安排一个教室之后,剩余的活动再分配一个教室,继续贪心选择…… 反例: A:[1,2)  B:[1,4) C:[5,6) D:[3,7) 已经按结束时间排好顺序,我们会选择教室1: A C教室2:  B教室3:  D需要3个教室.但是如果换一种安排方法,我们可以安排AD在一个教室,而BC在

hdu2037今年暑假不AC(贪心,活动安排问题)

今年暑假不AC Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 15   Accepted Submission(s) : 13 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description “今年暑假不AC?”“是的.”“那你干什么呢?”“看世界杯

贪心算法-活动安排问题

活动安排问题 问题描述 有n个需要使用同一资源的活动,且在同一时段只有一个活动能使用该资源. 每个活动i都有一个起始时间 si 和结束时间 fi ,且 si < ei .如果选择了活动 i,则它在半开时间区间 [si,ei) 内占用资源.若区间 [si, ei) 与区间 [sj,ej) 不相交,则称活动 i 与活动 j 是相容的. 该问题就是要安排这些活动使得尽量多的活动能不冲突地举行. 归纳: 活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合. 解题思路 每次总是选择具有最早完成时

算法设计与分析(三)贪心算法--活动安排问题

活动安排问题https://blog.csdn.net/qq_40452317/article/details/88875384 贪心算法汇总--喷水装置问题.会场安排问题.过河问题https://blog.csdn.net/liujiuxiaoshitou/article/details/69728714 原文地址:https://www.cnblogs.com/yasheng/p/12517250.html

51nod贪心算法入门-----活动安排问题

有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 输入 第1行:1个数N,线段的数量(2 <= N <= 10000) 第2 - N + 1行:每行2个数,线段的起点和终点(-10^9 <= S,E <= 10^9) 输出 输出最多可以选择的线段数量. 输入示例 3 1 5 2 3 3 6 输出示例 2 我们可以知道先安排最早结束的活动可以更多的安排活动.首先就是将所有的活动结束时间按先后顺序给排序:然后以结束时间为线索

51nod贪心算法入门-----活动安排问题2

题目大意就是给几个活动,问要几个教室能够弄完. 这个题目的想法就是把活动的开始——结束的时间看做是数轴上的一段线段,教室的个数就是在某点的时间厚度,求最大的时间厚度就是所需要的教室个数. 1 #include<stdio.h> 2 #include<iostream> 3 #include<stdlib.h> 4 #include<queue> 5 using namespace std; 6 struct node 7 { 8 int start; 9 i

贪心算法--活动安排

1 package cn.it; 2 3 import java.util.Arrays; 4 5 public class Tx { 6 public static void main(String[] args) { 7 int start[]={1,4,2,1,2,4,5}; 8 int end[]={5,6,3,2,4,5,6}; 9 int n=6; 10 boolean a[]= new boolean[n]; 11 sort(start,end,n); 12 int count =

贪心算法_活动安排问题_哈弗曼编码

问题表述:设有n个活动的集合E = {1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源.每个活i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si < fi .如果选择了活动i,则它在半开时间区间[si, fi)内占用资源.若区间[si, fi)与区间[sj, fj)不相交,则称活动i与活动j是相容的.也就是说,当si >= fj或sj >= fi时,活动i与活动j相容. 由于输入的活动以其完成时间的非减序排列,所以算法