完成至少 K 个任务的最短时间,每个任务完成后每个人都休息
给定一个大小为N的数组arr[] ,表示一个人完成一项任务所花费的时间。此外,一个数组restTime[]表示一个人在完成一项任务后需要休息的时间。每个人都独立于其他人,即他们可以同时在不同的任务上同时工作。给定一个整数K ,任务是找出至少需要多少时间来完成所有人的所有K个任务。
例子:
Input: arr[] = {1, 2, 4}, restTime[] = {1, 2, 2}, K = 5
Output: 5
Explanation: At t = 1, tasks task done = [1, 0, 0], Total task = 1
At t = 2, No of tasks completed = [1, 1, 0],
Total task = 1 + 1 = 2. Because 1st person was taking rest
At t = 3, No of tasks completed = [2, 1, 0],
Total task = 2 + 1 = 3, Because 2nd person was taking rest
At t = 4, No of tasks completed = [2, 1, 1],
Total task = 2 + 1 + 1 = 4, Because 1st and 2nd person was taking rest
At t = 5, No of tasks completed = [3, 1, 1].
Total task = 3 + 1 + 1 = 5. Minimum time taken = 5.
Input: arr[] = {1, 2, 4, 7, 8}, restTime[] = {4, 1, 2, 3, 1}, TotalTask = 2
Output: 2
方法:这个问题可以使用二分搜索来解决,基于以下观察:
The minimum time taken can be 1 and maximum time required can be very large. If in time x all the K tasks can be completed, then it is also possible that they can be completed in less than x time. Use this concept to apply binary search on the time required.
按照以下步骤实施上述方法:
- 创建一个变量st = 1,表示时间范围的起点, end = INT_MAX,终点。
- 在从st 到 end的范围内使用二分查找:
- 计算mid = st + (end – st)/2
- 检查是否可以在中间时间内完成K个任务:
- 如果可以完成,则设置 end = mid-1。
- 否则设置 st = mid+1。
- 最后返回st ,因为这将是所需的最短时间。
下面是上述方法的实现:
C++
// C++ code for the above approach
#include
using namespace std;
// Function to check if it is possible
// to complete atleast totaltask using
// current mid total time
bool timePossible(int mid, int totalTask,
vector& timeArr,
vector& restTime)
{
// Varible to store total task
int curTask = 0;
// Loop to check if it is possible
// to complete totalTask in mid time
for (int i = 0; i < timeArr.size(); i++) {
int totalTime
= timeArr[i] + restTime[i];
curTask += mid / totalTime;
if (mid % totalTime >= timeArr[i])
curTask++;
// Possible condition
if (curTask >= totalTask) {
return true;
}
}
// If possible print true
if (curTask >= totalTask) {
return true;
}
// Else return false
return false;
}
// Function to find minimum time taken
int minimumTimeTaken(vector& timeArr,
vector& restTime,
int totalTask)
{
// The ranges of time
int st = 1;
int end = INT_MAX;
// Variable to store minimum time
int minimumtime = 0;
while (st <= end) {
int mid = st + (end - st) / 2;
// If this mid value is possible
// try to minimise it
if (timePossible(mid, totalTask,
timeArr, restTime))
end = mid - 1;
else
st = mid + 1;
}
// Print the minimum time as answer
return st;
}
// Driver code
int main()
{
vector arr = { 1, 2, 4 };
vector restTime = { 1, 2, 2 };
int K = 5;
// Function call
cout << minimumTimeTaken(arr,
restTime, K);
return 0;
}
5
时间复杂度: O(N*log N)
辅助空间: O(1)