บทนำ
โจทย์: กำหนดจำนวนหน้าของหนังสือ n เล่ม (เรียงจากน้อยไปมาก) และ m นักเรียน ต้องจัดสรรหนังสือติดต่อกันให้แต่ละนักเรียน โดยต้องการให้ จำนวนหน้าสูงสุดที่นักเรียนคนใดคนหนึ่งต้องอ่าน น้อยที่สุด
ตัวอย่าง
books[] = {13, 43, 65, 87, 92}, m = 2 → Output: 179
การวิเคราะห์กรณี (m=2)
- [13] , [43,65,87,92] → max = 287
- [13,43] , [65,87,92] → max = 244
- [13,43,65] , [87,92] → max = 179 ← คำตอบ
- [13,43,65,87] , [92] → max = 208
แนวคิด: Binary Search
- ตั้งค่า low = 0, high = sum ของทุกหน้า
- mid = (low+high)/2 → ตรวจสอบว่าจัดสรรได้หรือไม่ด้วย max pages = mid
- ถ้าได้ → ลด high = mid-1, บันทึกคำตอบ
- ถ้าไม่ได้ → เพิ่ม low = mid+1
ตัวอย่างโค้ด C++
#include <bits/stdc++.h>
using namespace std;
bool isPossible(int arr[], int n, int m, int curr_min) {
int studentsRequired = 1, curr_sum = 0;
for (int i = 0; i < n; i++) {
if (arr[i] > curr_min) return false;
if (curr_sum + arr[i] > curr_min) {
studentsRequired++;
curr_sum = arr[i];
if (studentsRequired > m) return false;
} else curr_sum += arr[i];
}
return true;
}
int min_pages(int arr[], int n, int m) {
long long sum = 0;
if (n < m) return -1;
for (int i = 0; i < n; i++) sum += arr[i];
int minimum = 0, maximum = sum, result = INT_MAX;
while (minimum <= maximum) {
int mid = (minimum + maximum) / 2;
if (isPossible(arr, n, m, mid)) {
result = min(result, mid);
maximum = mid - 1;
} else minimum = mid + 1;
}
return result;
}
int main() {
int n = 5;
int books[] = {13, 43, 65, 87, 92};
int m = 2;
cout << "Minimum number of pages = " << min_pages(books, n, m);
return 0;
}
ผลลัพธ์
Minimum number of pages = 179