📌  相关文章
📜  找到在给定限制下完成所有工作的最短时间

📅  最后修改于: 2021-04-29 16:30:09             🧑  作者: Mango

给定一系列具有不同时间要求的工作。有K个完全相同的受让人,我们还得到了一个受让人完成一份工作所需的时间。找到完成以下条件的所有作业的最短时间。

  • 只能为受让人分配连续的工作。例如,不能为受让人分配作业1和3,但不能为其分配作业2。
  • 两个受让人无法共享(或共同指派)工作,即,不能将工作部分地分配给一个受让人,而部分不能分配给另一受让人。

输入 :

K:     Number of assignees available.
T:     Time taken by an assignee to finish one unit 
       of job
job[]: An array that represents time requirements of 
       different jobs.

例子 :

Input:  k = 2, T = 5, job[] = {4, 5, 10}
Output: 50
The minimum time required to finish all the jobs is 50.
There are 2 assignees available. We get this time by 
assigning {4, 5} to first assignee and {10} to second 
assignee.

Input:  k = 4, T = 5, job[] = {10, 7, 8, 12, 6, 8}
Output: 75
We get this time by assigning {10} {7, 8} {12} and {6, 8}

强烈建议您最小化浏览器,然后自己尝试。
这个想法是使用二进制搜索。想想我们是否有一个函数(例如isPossible())告诉我们是否有可能在给定的时间内和可用的受让人数量内完成所有工作。我们可以通过对答案进行二进制搜索来解决此问题。如果无法进行二进制搜索的中间点,则在后半部分搜索,否则在前半部分搜索。可以将最短时间的二进制搜索的下限设置为0。可以通过将所有给定的作业时间相加来获得上限。

现在如何实现isPossible()?可以使用贪婪方法来实现此函数。由于我们想知道是否可以在给定的时间内完成所有工作,因此我们遍历所有工作,并继续将工作分配给当前的受让人,同时可以在给定的期限内分配工作。当前受让人占用的时间超过给定时间时,创建一个新的受让人并开始为其分配工作。如果受让人的数量超过k,则返回false,否则返回true。

C++
// C++ program to find minimum time to finish all jobs with
// given number of assignees
#include
using namespace std;
  
// Utility function to get maximum element in job[0..n-1]
int getMax(int arr[], int n)
{
   int result = arr[0];
   for (int i=1; i result)
         result = arr[i];
    return result;
}
  
// Returns true if it is possible to finish jobs[] within
// given time 'time'
bool isPossible(int time, int K, int job[], int n)
{
    // cnt is count of current assignees required for jobs
    int cnt = 1;
  
    int curr_time = 0; //  time assigned to current assignee
  
    for (int i = 0; i < n;)
    {
        // If time assigned to current assignee exceeds max,
        // increment count of assignees.
        if (curr_time + job[i] > time) {
            curr_time = 0;
            cnt++;
        }
        else { // Else add time of job to current time and move
               // to next job.
            curr_time += job[i];
            i++;
        }
    }
  
    // Returns true if count is smaller than k
    return (cnt <= K);
}
  
// Returns minimum time required to finish given array of jobs
// k --> number of assignees
// T --> Time required by every assignee to finish 1 unit
// m --> Number of jobs
int findMinTime(int K, int T, int job[], int n)
{
    // Set start and end for binary search
    // end provides an upper limit on time
    int end = 0, start = 0;
    for (int i = 0; i < n; ++i)
        end += job[i];
  
    int ans = end; // Initialize answer
  
    // Find the job that takes maximum time
    int job_max = getMax(job, n);
  
    // Do binary search for minimum feasible time
    while (start <= end)
    {
        int mid = (start + end) / 2;
  
        // If it is possible to finish jobs in mid time
        if (mid >= job_max && isPossible(mid, K, job, n))
        {
            ans = min(ans, mid);  // Update answer
            end = mid - 1;
        }
        else
            start = mid + 1;
    }
  
    return (ans * T);
}
  
// Driver program
int main()
{
    int job[] =  {10, 7, 8, 12, 6, 8};
    int n = sizeof(job)/sizeof(job[0]);
    int k = 4, T = 5;
    cout << findMinTime(k, T, job, n) << endl;
    return 0;
}


Java
// Java program to find minimum time 
// to finish all jobs with given 
// number of assignees
  
class GFG
{
    // Utility function to get 
    // maximum element in job[0..n-1]
    static int getMax(int arr[], int n)
    {
    int result = arr[0];
    for (int i=1; i result)
            result = arr[i];
        return result;
    }
      
    // Returns true if it is possible to finish jobs[] 
    // within given time 'time'
    static boolean isPossible(int time, int K, 
                                    int job[], int n)
    {
        // cnt is count of current 
        // assignees required for jobs
        int cnt = 1;
          
        // time assigned to current assignee
        int curr_time = 0; 
      
        for (int i = 0; i < n;)
        {
            // If time assigned to current assignee 
            // exceeds max, increment count of assignees.
            if (curr_time + job[i] > time) {
                curr_time = 0;
                cnt++;
            }
              
            // Else add time of job to current 
            // time and move to next job.
            else 
            {
                curr_time += job[i];
                i++;
            }
        }
      
        // Returns true if count
        // is smaller than k
        return (cnt <= K);
    }
      
    // Returns minimum time required to 
    // finish given array of jobs
    // k --> number of assignees
    // T --> Time required by every assignee to finish 1 unit
    // m --> Number of jobs
    static int findMinTime(int K, int T, int job[], int n)
    {
        // Set start and end for binary search
        // end provides an upper limit on time
        int end = 0, start = 0;
        for (int i = 0; i < n; ++i)
            end += job[i];
              
        // Initialize answer
        int ans = end; 
      
        // Find the job that takes maximum time
        int job_max = getMax(job, n);
      
        // Do binary search for 
        // minimum feasible time
        while (start <= end)
        {
            int mid = (start + end) / 2;
      
            // If it is possible to finish jobs in mid time
            if (mid >= job_max && isPossible(mid, K, job, n))
            {
                // Update answer
                ans = Math.min(ans, mid); 
                  
                end = mid - 1;
            }
  
            else
                start = mid + 1;
        }
      
        return (ans * T);
    }
      
    // Driver program
    public static void main(String arg[])
    {
        int job[] = {10, 7, 8, 12, 6, 8};
        int n = job.length;
        int k = 4, T = 5;
        System.out.println(findMinTime(k, T, job, n));
    }
}
  
// This code is contributed by Anant Agarwal.


Python3
# Python program to find minimum
# time to finish all jobs with 
# given number of assignees 
  
# Utility function to get maximum
# element in job[0..n-1] 
def getMax(arr, n):
    result = arr[0]
    for i in range(1, n):
        if arr[i] > result: 
            result = arr[i] 
    return result
  
# Returns true if it is possible 
# to finish jobs[] within given 
# time 'time' 
def isPossible(time, K, job, n):
      
    # cnt is count of current 
    # assignees required for jobs 
    cnt = 1
  
    # time assigned to current assignee 
    curr_time = 0 
  
    i = 0
    while i < n:
          
        # If time assigned to current 
        # assignee exceeds max, increment
        # count of assignees. 
        if curr_time + job[i] > time: 
            curr_time = 0
            cnt += 1
        else:
              
            # Else add time of job to current 
            # time and move to next job. 
            curr_time += job[i] 
            i += 1
  
    # Returns true if count is smaller than k 
    return cnt <= K
  
# Returns minimum time required 
# to finish given array of jobs 
# k --> number of assignees 
# T --> Time required by every assignee to finish 1 unit 
# m --> Number of jobs 
def findMinTime(K, T, job, n):
      
    # Set start and end for binary search 
    # end provides an upper limit on time 
    end = 0
    start = 0
    for i in range(n):
        end += job[i] 
  
    ans = end # Initialize answer 
  
    # Find the job that takes maximum time 
    job_max = getMax(job, n) 
  
    # Do binary search for minimum feasible time 
    while start <= end: 
        mid = int((start + end) / 2) 
  
        # If it is possible to finish jobs in mid time 
        if mid >= job_max and isPossible(mid, K, job, n):
            ans = min(ans, mid) # Update answer 
            end = mid - 1
        else:
            start = mid + 1
  
    return ans * T
  
# Driver program 
if __name__ == '__main__':
    job = [10, 7, 8, 12, 6, 8]
    n = len(job) 
    k = 4
    T = 5
    print(findMinTime(k, T, job, n))
      
# this code is contributed by PranchalK


C#
// C# program to find minimum time 
// to finish all jobs with given 
// number of assignees
using System;
  
class GFG
{
    // Utility function to get 
    // maximum element in job[0..n-1]
    static int getMax(int []arr, int n)
    {
      int result = arr[0];
      for (int i=1; i result)
            result = arr[i];
        return result;
    }
      
    // Returns true if it is possible to
    // finish jobs[] within given time 'time'
    static bool isPossible(int time, int K, 
                          int []job, int n)
    {
        // cnt is count of current 
        // assignees required for jobs
        int cnt = 1;
          
        // time assigned to current assignee
        int curr_time = 0; 
      
        for (int i = 0; i < n;)
        {
            // If time assigned to current assignee 
            // exceeds max, increment count of assignees.
            if (curr_time + job[i] > time) {
                curr_time = 0;
                cnt++;
            }
              
            // Else add time of job to current 
            // time and move to next job.
            else
            {
                curr_time += job[i];
                i++;
            }
        }
      
        // Returns true if count
        // is smaller than k
        return (cnt <= K);
    }
      
    // Returns minimum time required to 
    // finish given array of jobs
    // k --> number of assignees
    // T --> Time required by every assignee to finish 1 unit
    // m --> Number of jobs
    static int findMinTime(int K, int T, int []job, int n)
    {
        // Set start and end for binary search
        // end provides an upper limit on time
        int end = 0, start = 0;
        for (int i = 0; i < n; ++i)
            end += job[i];
              
        // Initialize answer
        int ans = end; 
      
        // Find the job that takes maximum time
        int job_max = getMax(job, n);
      
        // Do binary search for 
        // minimum feasible time
        while (start <= end)
        {
            int mid = (start + end) / 2;
      
            // If it is possible to finish jobs in mid time
            if (mid >= job_max && isPossible(mid, K, job, n))
            {
                // Update answer
                ans = Math.Min(ans, mid); 
                  
                end = mid - 1;
            }
  
            else
                start = mid + 1;
        }
      
        return (ans * T);
    }
      
    // Driver program
    public static void Main()
    {
        int []job = {10, 7, 8, 12, 6, 8};
        int n = job.Length;
        int k = 4, T = 5;
        Console.WriteLine(findMinTime(k, T, job, n));
    }
}
  
// This code is contributed by Sam007.


输出:

75

感谢Gaurav Ahirwar提出上述解决方案。