📜  寻找完成所有工作的最低速度

📅  最后修改于: 2021-04-26 07:34:42             🧑  作者: Mango

给定一个数组A和一个整数H ,其中1\leq A[i] \leq 10^{9}len(A) \leq H \leq 10^{9} 。每个元素A [i]表示要完成的剩余待处理作业,而H表示要完成所有作业的剩余小时数。任务是找到最低速度在每小时工作在哪个人需要工作,完成H中小时的所有作业。

注意:如果A [i]要做的工作少于人的速度,则他完成了A [i]的所有工作,并且在此小时内不会再去下一个元素。

例子

Input: A[] = [3, 6, 7, 11], H = 8
Output: 4

Input: A[] = [30, 11, 23, 4, 20], H = 5
Output: 30

方法:如果此人可以K小时/小时的速度完成所有工作(在H小时内),那么他也可以以更高的速度完成所有工作。

如果当且仅当该人可以以K的工作速度完成时,将ispossible(K)设为true ,则当且仅当K> = X时,才存在ispossible(K)= True的一些X。

例如,在A = [ 3,6,7,11 ]H = 8的情况下,存在一些X = 4,因此ispossible(1)= ispossible(2)= ispossible(3)= False,而ispossible(4) = ispossible(5)=…= True

我们可以对ispossible(K)的值进行二进制搜索,以找到第一个X ,使ispossible(X)为True ,这将是我们的答案。

现在,由于即使作业完成也不允许在当前小时内从一个元素移动到另一个元素,否则K的最大可能值可能是数组A []中的最大元素。因此,要查找ispossible(K)的值(即,工作速度为K的人是否可以在H小时内完成所有工作),请在(1,max_element_of_array)范围内进行二进制搜索。

同样,对于每个大于0的A [i]作业,我们可以用Math.ceil(A [i] / K)((A [i] -1)/ K)+ 1小时来推论该人完成了该任务,并且我们将所有元素相加,以找到完成所有作业的总时间,然后将其与H进行比较,以检查是否有可能以K作业/小时的速度完成所有作业。

下面是上述方法的实现:

C++
// CPP program to find minimum speed
// to finish all jobs
  
#include 
using namespace std;
  
// Function to check if the person can do
// all jobs in H hours with speed K
bool isPossible(int A[], int n, int H, int K)
{
    int time = 0;
  
    for (int i = 0; i < n; ++i)
        time += (A[i] - 1) / K + 1;
  
    return time <= H;
}
  
// Function to return the minimum speed
// of person to complete all jobs
int minJobSpeed(int A[], int n, int H)
{
    // If H < N it is not possible to complete
    // all jobs as person can not move from
    // one element to another during current hour
    if (H < n)
        return -1;
  
    // Max element of array
    int* max = max_element(A, A + n);
  
    int lo = 1, hi = *max;
  
    // Use binary search to find smallest K
    while (lo < hi) {
        int mi = lo + (hi - lo) / 2;
        if (!isPossible(A, n, H, mi))
            lo = mi + 1;
        else
            hi = mi;
    }
  
    return lo;
}
  
// Driver program
int main()
{
    int A[] = { 3, 6, 7, 11 }, H = 8;
  
    int n = sizeof(A) / sizeof(A[0]);
  
    // Print required maxLenwer
    cout << minJobSpeed(A, n, H);
  
    return 0;
}


Java
// Java program to find minimum speed
// to finish all jobs
class GFG
{
  
// Function To findmax value in Array
static int findmax(int[] A)
{
    int r = A[0];
    for(int i = 1; i < A.length; i++)
    r = Math.max(r, A[i]);
    return r;
}
  
// Function to check if the person can do
// all jobs in H hours with speed K
static boolean isPossible(int[] A, int n, 
                          int H, int K)
{
    int time = 0;
  
    for (int i = 0; i < n; ++i)
        time += (A[i] - 1) / K + 1;
  
    return time <= H;
}
  
// Function to return the minimum speed
// of person to complete all jobs
static int minJobSpeed(int[] A, 
                       int n, int H)
{
    // If H < N it is not possible to 
    // complete all jobs as person can 
    // not move from one element to 
    // another during current hour
    if (H < n)
        return -1;
  
    // Max element of array
    int max = findmax(A);
  
    int lo = 1, hi = max;
  
    // Use binary search to find 
    // smallest K
    while (lo < hi) 
    {
        int mi = lo + (hi - lo) / 2;
        if (!isPossible(A, n, H, mi))
            lo = mi + 1;
        else
            hi = mi;
    }
  
    return lo;
}
  
// Driver Code
public static void main(String[] args)
{
    int[] A = { 3, 6, 7, 11 };
    int H = 8;
  
    int n = A.length;
  
    // Print required maxLenwer
    System.out.println(minJobSpeed(A, n, H));
}
}
  
// This code is contributed by mits


C#
// C# program to find minimum speed
// to finish all jobs
   
using System;
using System.Linq;
  
class GFG{
      
// Function to check if the person can do
// all jobs in H hours with speed K
static bool isPossible(int[] A, int n, int H, int K)
{
    int time = 0;
   
    for (int i = 0; i < n; ++i)
        time += (A[i] - 1) / K + 1;
   
    return time <= H;
}
   
// Function to return the minimum speed
// of person to complete all jobs
static int minJobSpeed(int[] A, int n, int H)
{
    // If H < N it is not possible to complete
    // all jobs as person can not move from
    // one element to another during current hour
    if (H < n)
        return -1;
   
    // Max element of array
    int max = A.Max();
   
    int lo = 1, hi = max;
   
    // Use binary search to find smallest K
    while (lo < hi) {
        int mi = lo + (hi - lo) / 2;
        if (!isPossible(A, n, H, mi))
            lo = mi + 1;
        else
            hi = mi;
    }
   
    return lo;
}
   
// Driver program
public static void Main()
{
    int[] A = { 3, 6, 7, 11 };
    int H = 8;
   
    int n = A.Length;
   
    // Print required maxLenwer
    Console.WriteLine(minJobSpeed(A, n, H));
}
}


Python3
# Python3 program to find minimum 
# speed to finish all jobs 
    
# Function to check if the person can do 
# all jobs in H hours with speed K 
def isPossible(A, n, H, K): 
   
    time = 0 
    
    for i in range(n): 
        time += (A[i] - 1) // K + 1 
    
    return time <= H 
   
   
# Function to return the minimum speed 
# of person to complete all jobs 
def minJobSpeed(A, n, H): 
   
    # If H < N it is not possible to complete 
    # all jobs as person can not move from 
    # one element to another during current hour 
    if H < n:
        return -1 
    
    # Max element of array 
    Max = max(A) 
    
    lo, hi = 1, Max 
    
    # Use binary search to find smallest K 
    while lo < hi:  
        mi = lo + (hi - lo) // 2 
        if not isPossible(A, n, H, mi): 
            lo = mi + 1 
        else:
            hi = mi 
       
    return lo 
   
if __name__ == "__main__":  
  
    A =  [3, 6, 7, 11]
    H = 8 
    
    n = len(A) 
    
    # Print required maxLenwer 
    print(minJobSpeed(A, n, H)) 
  
# This code is contributed by Rituraj Jain


输出:
4

时间复杂度: O(N * log(M)),其中N是数组的长度,M是max(A)。