活动选择问题
描述:
假定一个有n个活动(activity)的集合S={a1,a2,…,a**n},这些活动使用同一个资源(例如同一个阶梯教室),而这个资源在某个时刻只能供一个活动使用。每个活动a**i都有一个开始时间s**i和一个结束时间f**i,其中0<=s**i<f**i<=32767。如果被选中,任务a**i发生在半开时间区间[s**i,f**i)期间。如果两个活动a**i和a**j满足[s**i,f**i)和[s**j,f**j)不重叠,则称它们是兼容的。也就说,若s**i>=f**j或s**j>=f**i,则a**i和a**j是兼容的。在活动选择问题中,我们希望选出一个最大兼容活动集。
输入格式:
第一行一个整数n(n≤1000);
接下来的n行,每行两个整数,第一个s**i,第二个是f**i(0<=s**i<f**i<=32767)。
输出格式:
输出最多能安排的活动个数。
输入样例:
11
3 5
1 4
12 14
8 12
0 6
8 11
6 10
5 7
3 8
5 9
2 13
输出样例:
4
import java.util.Scanner;
public class Activity_selection_questions {
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int []s = new int[n];
int []f = new int[n];
for(int i = 0;i < n;i++){
s[i] = scanner.nextInt();
f[i] = scanner.nextInt();
}
Sort(s,f);
Select(s,f);
}
public static void Select(int []s,int []f){
int temp = 0;//临时存储上一个活动的位置
int num = 0;//活动的个数
int fir = 0;//第一个开始时间
int las = 32767;//结束时间 <= 32767s
int n = s.length;
boolean flag = true;
int []sel = new int[n];
while (flag){
flag = false;
for(int i = 0;i < n;i++){
if(f[i] < las && s[i] >= fir) {//结束时间小于32767并且开始时间大于上一个活动的结束时间
las = f[i];
temp = i;
flag = true;
}
if(las != 32767) {
// sel[num++] = temp;
num++;
fir = f[temp];
las = 32767;
}
}
}
System.out.print(num);
}
public static void Sort(int []s,int []f){//希尔排序 开始时间升序
int i,j,key,key1,mid;
for(mid = f.length / 2; mid > 0; mid /= 2){
for(i = mid; i < f.length; i++){
j = i;
key = f[j];
key1 = s[j];
if (f[j] < f[j - mid]) {
while(j - mid >= 0 && f[j - mid] > key){
f[j] = f[j - mid];
s[j] = s[j - mid];
j = j - mid;
}
f[j] = key;
s[j] = key1;
}
}
}
}
}