給定 n 個活動,每個有開始時間 sᵢ 和結束時間 fᵢ。選擇最大子集,使任兩活動不重疊(即 sⱼ ≥ fᵢ 或 sᵢ ≥ fⱼ)。
按結束時間 fᵢ 遞增排序,依序選擇:第一個必選,之後若某活動開始時間 ≥ 最後被選活動的結束時間,則選擇它。
struct Object { int id, start, finish; };
void Sort(struct Object a[], int n) {
for (int i=0; i<n; i++)
for (int j=0; j<n-i-1; j++)
if (a[j].finish > a[j+1].finish) swap(a[j], a[j+1]);
}
int GreedySelector(struct Object a[], int n) {
int count = 1, last = 0;
for (int i=1; i<n; i++)
if (a[i].start >= a[last].finish) {
count++; last = i;
}
return count;
}
typedef struct { int start, finish, number; } arrange;
arrange plans[MAX];
int partition(arrange a[], int p, int q) {
int i=p, j=q+1;
while (1) {
do i++; while (a[i].finish < a[p].finish && i<q);
do j--; while (a[j].finish > a[p].finish);
if (i<j) swap(a[i], a[j]); else break;
}
swap(a[p], a[j]); return j;
}
void quicksort(arrange a[], int p, int q) {
if (p<q) { int j=partition(a,p,q); quicksort(a,p,j-1); quicksort(a,j+1,q); }
}
int greedySelector(arrange p[], int n) {
int count=1, last=0;
for (int i=1; i<n; i++)
if (p[i].start >= p[last].finish) { count++; last=i; }
return count;
}
11 活動:
1: 1-4 2: 3-5 3: 0-6 4: 5-7 5: 3-8
6: 5-9 7: 6-10 8: 8-11 9: 8-12 10: 2-13
11: 12-14
排序後結束時間: 4,5,6,7,8,9,10,11,12,13,14
貪心選擇: 1(1-4) → 4(5-7) → 8(8-11) → 11(12-14)
最多 4 個活動
活動安排問題是貪心算法「最早結束時間優先」策略的標準範例,展示了如何將區間衝突轉化為排序後的線性掃描,極具工程實用價值。