活动安排问题:假设某社团某一天要组织n个活动 E = {1, 2, 3 … n},其中每个活动都要求使用同一礼堂,而且在同一时间内只有一个活动能使用这个礼堂。每个活动 i 都有一个要求使用礼堂的起始时间 si 和结束时间 fi, 且有 si < fi。若区间(si,fi)和(sj,fj)不相交,则称活动 i 与活动 j 是相容的。现在给定 n 个活动的开始时间和结束时间,请设计一个活动安排方案,使得安排的相容活动数目最多。
/**
* 思路:
* 将活动按照结束时间进行从小到大排序。然后用i代表第i个活动,start[i]代表第i个活动开始时间,end[i]代表第i个活动的结束时间。
* 按照从小到大排序,挑选出结束时间尽量早的活动,并且满足后一个活动的起始时间晚于前一个活动的结束时间,全部找出这些活动就是最大的相容活动子集合。
*/
// 注:本题中给的示例,结束时间已经是升序,所以不需要再排序。如果不是升序还要先排序
public class Main {
static int n = 12;
public static void main(String[] args) {
int[] start = {1, 2, 0, 5, 3, 5, 6, 8, 8, 2, 12, 15};
int[] end = {3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 18};
boolean[] judge = new boolean[n]; // 记录活动是否能安排,true则安排,false不安排
int res = greedySelect(start, end, judge);
// 输出结果
System.out.println(res);
for(int i = 0; i < n; i++){
if(judge[i]){
System.out.println("下标:" + i + ",[" + start[i] + "," + end[i] + "]");
}
}
}
public static int greedySelect(int[] start, int[] end, boolean[] judge){
judge[0] = true;
int count = 1;
int j = 0;
for(int i = 1; i < n; i++){
if(start[i] >= end[j]){ // 如果后一个活动的起始时间晚于前一个活动的结束时间
judge[i] = true;
j = i;
count++;
}else{
judge[i] = false;
}
}
return count;
}
}