แนวคิด
ในส่วนที่เกี่ยวกับอาร์เรย์ของงานที่กำหนดซึ่งมีข้อกำหนดด้านเวลาต่างกัน มีผู้รับมอบหมายที่เหมือนกันจำนวน k ราย และเรายังได้รับแจ้งด้วยว่าผู้รับมอบหมายใช้เวลาเท่าใดในการทำงานหนึ่งหน่วยของงาน งานของเราคือกำหนดเวลาขั้นต่ำในการทำงานทั้งหมดให้เสร็จสิ้นโดยมีข้อจำกัดดังต่อไปนี้
-
ข้อจำกัดแรกคือสามารถกำหนดผู้รับโอนได้เฉพาะงานที่ต่อเนื่องกัน
ตัวอย่างเช่น ในที่นี้ ผู้รับมอบหมายสามารถมอบหมายงานที่ตำแหน่ง 1 และ 2 ได้ แต่ไม่ใช่ที่ตำแหน่ง 3 ในอาร์เรย์
-
ข้อจำกัดที่สองคือผู้รับมอบหมายสองคนไม่สามารถแบ่งปัน (หรือมอบหมายร่วมกัน) งานได้ ซึ่งหมายความว่างานไม่สามารถมอบหมายบางส่วนให้กับผู้รับมอบหมายรายหนึ่งและบางส่วนให้กับผู้อื่นได้บางส่วน
อินพุต
k - ระบุจำนวนผู้รับมอบหมายที่พร้อมใช้งาน
t − ระบุเวลาที่ผู้ได้รับมอบหมายทำงานให้เสร็จหนึ่งหน่วย
JOB[] - ระบุอาร์เรย์ที่แสดงถึงข้อกำหนดด้านเวลาของงานที่แตกต่างกัน
อินพุต
k = 2, t = 4, JOB[] = {5, 6, 12} ผลลัพธ์
48
เวลาขั้นต่ำที่จำเป็นในการทำงานทั้งหมดให้เสร็จสิ้นคือ 48
มีผู้รับมอบอำนาจ 2 คน เราได้รับเวลานี้โดยมอบหมาย {5, 6} ให้กับผู้รับมอบหมายคนแรกและ {12} ให้กับผู้รับมอบหมายที่สอง
อินพุต
k = 4, t = 5, JOB[] = {12, 6, 9, 15, 5, 9} ผลลัพธ์
75
เราได้เวลานี้โดยมอบหมาย {12} {6, 9} {15} และ {5, 9}
วิธีการ
ตอนนี้แนวคิดคือการนำ Binary Search ไปใช้ สมมติว่าเรามีฟังก์ชัน (เช่น isPossible()) ที่ระบุว่าเป็นไปได้หรือไม่ที่จะทำงานทั้งหมดให้เสร็จสิ้นภายในเวลาที่กำหนดและจำนวนผู้ได้รับมอบหมาย ที่นี่ เราสามารถแก้ปัญหานี้ได้โดยทำการค้นหาแบบไบนารีเพื่อหาคำตอบ จะเห็นได้ว่าถ้าจุดกึ่งกลางของการค้นหาแบบไบนารีเป็นไปไม่ได้ ให้ค้นหาในครึ่งหลัง มิฉะนั้นจะค้นหาในครึ่งแรก ขอบเขตล่างสำหรับการค้นหาไบนารีสำหรับเวลาที่เล็กที่สุดสามารถตั้งค่าเป็น 0 ที่นี่ ขอบเขตบนสามารถรับได้โดยเพิ่มเวลางานที่ให้มาทั้งหมด
ปัจจุบันมีคำถามเกิดขึ้นว่าจะใช้ isPossible() อย่างไร เราสามารถใช้ฟังก์ชันนี้ได้โดยใช้ Greedy Approach เนื่องจากเราต้องการทราบว่าสามารถทำงานทั้งหมดให้เสร็จภายในเวลาที่กำหนดได้หรือไม่ เราจึงตรวจสอบงานทั้งหมดและดูแลการมอบหมายงานให้กับผู้รับมอบหมายปัจจุบันทีละงาน ในขณะเดียวกัน เราควรจำไว้ว่าสามารถมอบหมายงานได้ภายในระยะเวลาที่กำหนด ในขณะนั้น เมื่อเวลาที่ใช้โดยผู้รับมอบหมายปัจจุบันข้ามเวลาที่กำหนด ให้สร้างผู้รับมอบหมายใหม่และเริ่มมอบหมายงานให้กับผู้รับมอบหมายนั้น จะเห็นได้ว่าหากจำนวนผู้ได้รับมอบหมายเพิ่มขึ้น ขอบคุณ ให้คืนค่าเท็จ ไม่เช่นนั้นให้คืนค่าเป็น จริง
ตัวอย่าง
// C++ program to find minimum time to finish all jobs with
// given number of assignees
#include<bits/stdc++.h>
using namespace std;
// Shows utility function to get maximum element in job1[0..n1-1]
int getMax(int arr1[], int n1){
int result1 = arr1[0];
for (int i=1; i<n1; i++)
if (arr1[i] > result1)
result1 = arr1[i];
return result1;
}
// Now returns true if it is possible to finish jobs1[] within
// given time 'time1'
bool isPossible(int time1, int K1, int job1[], int n1){
// Here, cnt1 is count of current assignees required for jobs
int cnt1 = 1;
int curr_time1 = 0; // Indicates time assigned to current
//assignee
for (int i = 0; i < n1;){
// Now if time assigned to current assignee exceeds max1,
// increment count1 of assignees.
if (curr_time1 + job1[i] > time1) {
curr_time1 = 0;
cnt1++;
}
else { // Else add time of job to current time and move
// to next job.
curr_time1 += job1[i];
i++;
}
}
//Now returns true if count is smaller than k
return (cnt1 <= K1);
}
// Here, returns minimum time required to finish given array of
//jobs
// K1 --> number of assignees
// T1 --> Time required by every assignee to finish 1 unit
// n1 --> Number of jobs
int findMinTime(int K1, int T1, int job1[], int n1){
// Used to set start and end for binary search
// end provides an upper limit on time1
int end1 = 0, start1 = 0;
for (int i = 0; i < n1; ++i)
end1 += job1[i];
int ans1 = end1; // Used to initialize answer
// Determine the job that takes maximum time
int job_max1 = getMax(job1, n1);
// Perform binary search for minimum feasible time
while (start1 <= end1){
int mid1 = (start1 + end1) / 2;
// Now if it is possible to complete jobs in mid time
if (mid1 >= job_max1 && isPossible(mid1, K1, job1, n1)){
ans1 = min(ans1, mid1); // Used to update answer
end1 = mid1 - 1;
}
else
start1 = mid1 + 1;
}
return (ans1 * T1);
}
// Driver program
int main(){
int job1[] = {12, 6, 9, 15, 5, 9};
// int job1[] = {5, 6, 12};
int n1 = sizeof(job1)/sizeof(job1[0]);
int k1=4, T1=5;
// int k1=2, T1=4;
cout << findMinTime(k1, T1, job1, n1) << endl;
return 0;
} ผลลัพธ์
75