📜  分配最小页数

📅  最后修改于: 2021-09-16 10:52:58             🧑  作者: Mango

给定 n 本书和 m 名学生的页数。书籍按页数升序排列。每个学生都被分配阅读一些连续的书籍。任务是以分配给学生的最大页数最少的方式分配书籍。
例子 :

Input : pages[] = {12, 34, 67, 90}
        m = 2
Output : 113
Explanation:
There are 2 number of students. Books can be distributed 
in following fashion : 
  1) [12] and [34, 67, 90]
      Max number of pages is allocated to student 
      2 with 34 + 67 + 90 = 191 pages
  2) [12, 34] and [67, 90]
      Max number of pages is allocated to student
      2 with 67 + 90 = 157 pages 
  3) [12, 34, 67] and [90]
      Max number of pages is allocated to student 
      1 with 12 + 34 + 67 = 113 pages

Of the 3 cases, Option 3 has the minimum pages = 113. 

这个想法是使用二分搜索。我们将页数的值固定为当前最小值和最大值的中间值。我们将最小值和最大值分别初始化为 0 和所有页面的总和。如果当前的 mid 可以是一个解决方案,那么我们搜索下半部分,否则我们搜索上半部分。
现在问题来了,如何检查中间值是否可行?基本上,我们需要检查是否可以以最大数量不超过当前值的方式将页面分配给所有学生。为此,我们按顺序为每个学生分配页面,而当前分配的页面数不超过该值。在这个过程中,如果学生人数变得超过m,那么这个解决方案是不可行的。否则可行。
下面是上述想法的实现。

C++
// C++ program for optimal allocation of pages
#include
using namespace std;
 
// Utility function to check if current minimum value
// is feasible or not.
bool isPossible(int arr[], int n, int m, int curr_min)
{
    int studentsRequired = 1;
    int curr_sum = 0;
 
    // iterate over all books
    for (int i = 0; i < n; i++)
    {
        // check if current number of pages are greater
        // than curr_min that means we will get the result
        // after mid no. of pages
        if (arr[i] > curr_min)
            return false;
 
        // count how many students are required
        // to distribute curr_min pages
        if (curr_sum + arr[i] > curr_min)
        {
            // increment student count
            studentsRequired++;
 
            // update curr_sum
            curr_sum = arr[i];
 
            // if students required becomes greater
            // than given no. of students,return false
            if (studentsRequired > m)
                return false;
        }
 
        // else update curr_sum
        else
            curr_sum += arr[i];
    }
    return true;
}
 
// function to find minimum pages
int findPages(int arr[], int n, int m)
{
    long long sum = 0;
 
    // return -1 if no. of books is less than
    // no. of students
    if (n < m)
        return -1;
 
    // Count total number of pages
    for (int i = 0; i < n; i++)
        sum += arr[i];
 
    // initialize start as 0 pages and end as
    // total pages
    int start = 0, end = sum;
    int result = INT_MAX;
 
    // traverse until start <= end
    while (start <= end)
    {
        // check if it is possible to distribute
        // books by using mid as current minimum
        int mid = (start + end) / 2;
        if (isPossible(arr, n, m, mid))
        {
            // update result to current distribution
              // as it's the best we have found till now.
              result = mid;
 
            // as we are finding minimum and books
            // are sorted so reduce end = mid -1
            // that means
            end = mid - 1;
        }
 
        else
            // if not possible means pages should be
            // increased so update start = mid + 1
            start = mid + 1;
    }
 
    // at-last return minimum no. of  pages
    return result;
}
 
// Drivers code
int main()
{
    //Number of pages in books
    int arr[] = {12, 34, 67, 90};
    int n = sizeof arr / sizeof arr[0];
    int m = 2; //No. of students
 
    cout << "Minimum number of pages = "
         << findPages(arr, n, m) << endl;
    return 0;
}


Java
// Java program for optimal allocation of pages
 
public class GFG
{
    // Utility method to check if current minimum value
    // is feasible or not.
    static boolean isPossible(int arr[], int n, int m, int curr_min)
    {
        int studentsRequired = 1;
        int curr_sum = 0;
      
        // iterate over all books
        for (int i = 0; i < n; i++)
        {
            // check if current number of pages are greater
            // than curr_min that means we will get the result
            // after mid no. of pages
            if (arr[i] > curr_min)
                return false;
      
            // count how many students are required
            // to distribute curr_min pages
            if (curr_sum + arr[i] > curr_min)
            {
                // increment student count
                studentsRequired++;
      
                // update curr_sum
                curr_sum = arr[i];
      
                // if students required becomes greater
                // than given no. of students,return false
                if (studentsRequired > m)
                    return false;
            }
      
            // else update curr_sum
            else
                curr_sum += arr[i];
        }
        return true;
    }
      
    // method to find minimum pages
    static int findPages(int arr[], int n, int m)
    {
        long sum = 0;
      
        // return -1 if no. of books is less than
        // no. of students
        if (n < m)
            return -1;
      
        // Count total number of pages
        for (int i = 0; i < n; i++)
            sum += arr[i];
      
        // initialize start as 0 pages and end as
        // total pages
        int start = 0, end = (int) sum;
        int result = Integer.MAX_VALUE;
      
        // traverse until start <= end
        while (start <= end)
        {
            // check if it is possible to distribute
            // books by using mid is current minimum
            int mid = (start + end) / 2;
            if (isPossible(arr, n, m, mid))
            {
                // update result to current distribution
                // as it's the best we have found till now.
                result = mid;
      
                // as we are finding minimum and books
                // are sorted so reduce end = mid -1
                // that means
                end = mid - 1;
            }
      
            else
                // if not possible means pages should be
                // increased so update start = mid + 1
                start = mid + 1;
        }
      
        // at-last return minimum no. of  pages
        return result;
    }
     
    // Driver Method
    public static void main(String[] args)
    {
        //Number of pages in books
        int arr[] = {12, 34, 67, 90};
        
        int m = 2; //No. of students
      
        System.out.println("Minimum number of pages = " +
                          findPages(arr, arr.length, m));
    }
}


Python3
# Python3 program for optimal allocation of pages
 
# Utility function to check if
# current minimum value is feasible or not.
def isPossible(arr, n, m, curr_min):
    studentsRequired = 1
    curr_sum = 0
 
    # iterate over all books
    for i in range(n):
 
        # check if current number of pages are
        # greater than curr_min that means
        # we will get the result after
        # mid no. of pages
        if (arr[i] > curr_min):
            return False
 
        # count how many students are required
        # to distribute curr_min pages
        if (curr_sum + arr[i] > curr_min):
 
            # increment student count
            studentsRequired += 1
 
            # update curr_sum
            curr_sum = arr[i]
 
            # if students required becomes greater
            # than given no. of students, return False
            if (studentsRequired > m):
                return False
 
        # else update curr_sum
        else:
            curr_sum += arr[i]
 
    return True
 
# function to find minimum pages
def findPages(arr, n, m):
 
    sum = 0
 
    # return -1 if no. of books is
    # less than no. of students
    if (n < m):
        return -1
 
    # Count total number of pages
    for i in range(n):
        sum += arr[i]
 
    # initialize start as 0 pages and
    # end as total pages
    start, end = 0, sum
    result = 10**9
 
    # traverse until start <= end
    while (start <= end):
 
        # check if it is possible to distribute
        # books by using mid as current minimum
        mid = (start + end) // 2
        if (isPossible(arr, n, m, mid)):
 
            # update result to current distribution
              # as it's the best we have found till now.
            result = mid
 
            # as we are finding minimum and books
            # are sorted so reduce end = mid -1
            # that means
            end = mid - 1
 
        else:
            # if not possible means pages should be
            # increased so update start = mid + 1
            start = mid + 1
 
    # at-last return minimum no. of pages
    return result
 
# Driver Code
 
# Number of pages in books
arr = [12, 34, 67, 90]
n = len(arr)
m = 2   # No. of students
 
print("Minimum number of pages = ",
              findPages(arr, n, m))
 
# This code is contributed by Mohit Kumar


C#
// C# program for optimal
// allocation of pages
using System;
 
class GFG
{
 
// Utility function to check
// if current minimum value
// is feasible or not.
static bool isPossible(int []arr, int n,
                       int m, int curr_min)
{
    int studentsRequired = 1;
    int curr_sum = 0;
 
    // iterate over all books
    for (int i = 0; i < n; i++)
    {
        // check if current number of
        // pages are greater than curr_min
        // that means we will get the
        // result after mid no. of pages
        if (arr[i] > curr_min)
            return false;
 
        // count how many students
        // are required to distribute
        // curr_min pages
        if (curr_sum + arr[i] > curr_min)
        {
            // increment student count
            studentsRequired++;
 
            // update curr_sum
            curr_sum = arr[i];
 
            // if students required becomes
            // greater than given no. of
            // students, return false
            if (studentsRequired > m)
                return false;
        }
 
        // else update curr_sum
        else
            curr_sum += arr[i];
    }
    return true;
}
 
// function to find minimum pages
static int findPages(int []arr,
                     int n, int m)
{
    long sum = 0;
 
    // return -1 if no. of books
    // is less than no. of students
    if (n < m)
        return -1;
 
    // Count total number of pages
    for (int i = 0; i < n; i++)
        sum += arr[i];
 
    // initialize start as 0 pages
    // and end as total pages
    int start = 0, end = (int)sum;
    int result = int.MaxValue;
 
    // traverse until start <= end
    while (start <= end)
    {
        // check if it is possible to
        // distribute books by using
        // mid as current minimum
        int mid = (start + end) / 2;
        if (isPossible(arr, n, m, mid))
        {
            // update result to current distribution
              // as it's the best we have found till now.
              result = mid;
 
            // as we are finding minimum and
            // books are sorted so reduce
            // end = mid -1 that means
            end = mid - 1;
        }
 
        else
            // if not possible means pages
            // should be increased so update
            // start = mid + 1
            start = mid + 1;
    }
 
    // at-last return
    // minimum no. of pages
    return result;
}
 
// Drivers code
static public void Main ()
{
     
//Number of pages in books
int []arr = {12, 34, 67, 90};
int n = arr.Length;
int m = 2; // No. of students
 
Console.WriteLine("Minimum number of pages = " +
                          findPages(arr, n, m));
}
}
 
// This code is contributed by anuj_67.


PHP
 $curr_min)
            return false;
 
        // count how many students are
        // required to distribute
        // curr_min pages
        if ($curr_sum + $arr[$i] > $curr_min)
        {
            // increment student count
            $studentsRequired++;
 
            // update curr_sum
            $curr_sum = $arr[$i];
 
            // if students required becomes
            // greater than given no. of
            // students, return false
            if ($studentsRequired > $m)
                return false;
        }
 
        // else update curr_sum
        else
            $curr_sum += $arr[$i];
    }
    return true;
}
 
// function to find minimum pages
function findPages($arr, $n, $m)
{
    $sum = 0;
 
    // return -1 if no. of books is
    // less than no. of students
    if ($n < $m)
        return -1;
 
    // Count total number of pages
    for ($i = 0; $i < $n; $i++)
        $sum += $arr[$i];
 
    // initialize start as 0 pages
    // and end as total pages
    $start = 0;
    $end = $sum;
    $result = PHP_INT_MAX;
 
    // traverse until start <= end
    while ($start <= $end)
    {
        // check if it is possible to
        // distribute books by using
        // mid as current minimum
        $mid = (int)($start + $end) / 2;
        if (isPossible($arr, $n, $m, $mid))
        {
            // update result to current distribution
              // as it's the best we have found till now
            $result = $mid;
 
            // as we are finding minimum and
            // books are sorted so reduce
            // end = mid -1 that means
            $end = $mid - 1;
        }
 
        else
            // if not possible means pages
            // should be increased so update
            // start = mid + 1
            $start = $mid + 1;
    }
 
    // at-last return minimum
    // no. of pages
    return $result;
}
 
// Driver code
 
// Number of pages in books
$arr = array(12, 34, 67, 90);
$n = count($arr);
$m = 2; // No. of students
 
echo "Minimum number of pages = ",
    findPages($arr, $n, $m), "\n";
 
// This code is contributed by Sach_Code
?>


Javascript


输出 :

Minimum number of pages = 113

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