一、問題描述
設有n個活動的集合E={1, 2,----,n},其中每個活動都要求使用同一資源,而在同一時間內只有一個活動能使用這一資源。每個活動i都有一個要求使用該資源的起始時間si和一個結束時間fi,且si <fi。如果選擇了活動i,則它在半開時間區間[si, f)內佔用資源。若區間[si,fi)與區間[sj, f)不相交,則稱活動i與活動j是相容的。也就是說,當si≥fj 或sj≥fi時,活動i與活動j相容。活動安排問題就是要在所給的活動集合中選出最大的相容活動子集合。
二、貪心策略
先安排結束時間最早的‘活動
三、核心算法
public int greedySelector(int[] s, int[] f, boolean[] a) {
int n = s.length - 1;
a[1] = true;//第一個活動被選中
int j = 1;
int count = 1;//被選中活動的數量,默認第一個活動被選中
for (int i = 2; i <= n; i++) {
if (s[i] >= f[j]) {//下一個活動開始時間大於大於等於上一個活動結束時間
a[i] = true;
j = i;
count++;
} else {
a[i] = false;
}
}
return count;
}
四、整體代碼
package 第四章;
import java.util.Arrays;
public class Act {
public int greedySelector(int[] s, int[] f, boolean[] a) {
int n = s.length - 1;
a[1] = true;//第一個活動被選中
int j = 1;
int count = 1;//被選中活動的數量,默認第一個活動被選中
for (int i = 2; i <= n; i++) {
if (s[i] >= f[j]) {//下一個活動開始時間大於大於等於上一個活動結束時間
a[i] = true;
j = i;
count++;
} else {
a[i] = false;
}
}
return count;
}
public static void main(String[] args) {
int s[] = {-1, 1, 3, 0, 5, 3, 5, 6, 8, 8, 2, 12};//默認下標從1開始(已非減序排好序),初始的-1無用
int f[] = {-1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
boolean[] a = new boolean[s.length];
Act ac = new Act();
int counts = ac.greedySelector(s, f, a);
System.out.println("活動集合中最大相容活動數量爲:" + counts);
for (int i = 1; i <= s.length - 1; i++) {
if (a[i]) {
System.out.println("第" + i + "活動被選中");
}
}
}
}