กำหนดรายการงาน แต่ละงานมี Start Time, Finish Time, Profit ต้องการเลือก Subset ของงานที่ ไม่ทับซ้อนกัน และให้ **กำไรรวมสูงสุด**
ตัวอย่าง Input และ Output
Jobs (Start, Finish, Profit): 1: (3, 5, 25) 2: (1, 2, 50) 3: (6, 15, 75) 4: (2, 100, 100) Output: The maximum profit: 150 Optimal: Job 2 + Job 4 (50+100) หรือ Job 2 + Job 1 + Job 3 (50+25+75)
อัลกอริทึม Dynamic Programming
ฟังก์ชัน findMaxProfit(jobList, n)
ขั้นตอน:
- Sort งานตาม Finish Time (สำคัญมาก)
- สร้างตาราง
table[n]โดยtable[i]= max profit จากงาน 0..i table[0] = job[0].profit- for i = 1 ถึง n-1:
addProfit = job[i].profit- หา
nonConflict= index ของงานล่าสุดที่ finish ≤ job[i].start (Binary Search ให้ O(log n)) - ถ้ามี nonConflict →
addProfit += table[nonConflict] table[i] = max(addProfit, table[i-1])
- คืน
table[n-1]
ตัวอย่างโค้ด C++
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct Job { int start, end, profit; };
bool comp(Job a, Job b) { return a.end < b.end; }
int nonConflictJob(Job jobs[], int i) {
for (int j = i-1; j >= 0; j--)
if (jobs[j].end <= jobs[i].start) return j;
return -1;
}
int findMaxProfit(Job jobList[], int n) {
sort(jobList, jobList+n, comp);
int *table = new int[n];
table[0] = jobList[0].profit;
for (int i = 1; i < n; i++) {
int addProfit = jobList[i].profit;
int l = nonConflictJob(jobList, i);
if (l != -1) addProfit += table[l];
table[i] = max(addProfit, table[i-1]);
}
int result = table[n-1];
delete[] table;
return result;
}
int main() {
Job jobList[] = {{3,5,25}, {1,2,50}, {6,15,75}, {2,100,100}};
int n = 4;
cout << "The maximum profit: " << findMaxProfit(jobList, n);
return 0;
}
Output
The maximum profit: 150
ความซับซ้อน
- Time: O(n²) (Linear search nonConflict) หรือ O(n log n) (Binary Search)
- Space: O(n)
Binary Search Optimization (O(n log n))
int binarySearch(Job jobs[], int start, int end, int target) {
while (start <= end) {
int mid = (start + end) / 2;
if (jobs[mid].end <= target) {
if (jobs[mid+1].end <= target) start = mid + 1;
else return mid;
} else end = mid - 1;
}
return -1;
}
ความสัมพันธ์กับ Activity Selection
Activity Selection = Weighted Job Scheduling ที่ profit ทุกงาน = 1 (Greedy ได้) แต่ Weighted ต้องใช้ DP