📌  相关文章
📜  找到在给定约束下完成所有作业的最短时间

📅  最后修改于: 2021-10-26 06:05:15             🧑  作者: 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.


Javascript


输出:

75

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程