Allocate minimum number of pages

22 Jun, 2022
Given number of pages in n different books and m students. The books are arranged in ascending order of number of pages. Every student is assigned to read some consecutive books. The task is to assign books in such a way that the maximum number of pages assigned to a student is minimum. Example :  
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. 
The idea is to use Binary Search. We fix a value for the number of pages as mid of current minimum and maximum. We initialize minimum and maximum as 0 and sum-of-all-pages respectively. If a current mid can be a solution, then we search on the lower half, else we search in higher half.Now the question arises, how to check if a mid value is feasible or not? Basically, we need to check if we can assign pages to all students in a way that the maximum number doesn’t exceed current value. To do this, we sequentially assign pages to every student while the current number of assigned pages doesn’t exceed the value. In this process, if the number of students becomes more than m, then the solution is not feasible. Else feasible.Below is an implementation of above idea. 
C++
C
Java
Python3
C#
PHP
Javascript
// C++ program for optimal allocation of pages#include <bits/stdc++.h>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 pagesint 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 codeint 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;} // This code is contributed by Aditya Kumar (adityakumar129)
// C program for optimal allocation of pages#include <limits.h>#include <stdbool.h>#include <stdio.h> // 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 pagesint 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 codeint 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     printf("Minimum number of pages = %d\n",           findPages(arr, n, m));    return 0;} // This code is contributed by Aditya Kumar (adityakumar129)
// 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++)       {          curr_sum += arr[i];            if(curr_sum > curr_min)           {                                         studentsRequired++ ;   // increment student count                              curr_sum = arr[i] ;    // update curr_sum           }       }              return studentsRequired <= m;    }          // method to find minimum pages    static int findPages(int arr[], int n, int m)    {        int 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 arr[n-1] pages(minimum answer possible) and end as        // total pages(maximum answer possible)        int start = arr[n-1], end = 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 - start)/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 so,                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)    {               int arr[] = {12, 34, 67, 90};  //Number of pages in books                int m = 2;  //No. of students              System.out.println("Minimum number of pages = " + findPages(arr, arr.length, m));    }} // This code is contributed by Aditya Kumar (adityakumar129)
# 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 pagesdef 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 booksarr = [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# program for optimal// allocation of pagesusing 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 pagesstatic 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 codestatic public void Main (){     //Number of pages in booksint []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// PHP program for optimal allocation// of pages // Utility function to check if current// minimum value is feasible or not. function isPossible($arr, $n, $m,                    $curr_min){    $studentsRequired = 1;    $curr_sum = 0;     // iterate over all books    for ( $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 pagesfunction 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?>
<script>// Javascript program for optimal allocation of pages  // Utility method to check if current minimum value    // is feasible or not.function isPossible(arr,n,m,curr_min){    let studentsRequired = 1;    let curr_sum = 0;       // iterate over all books    for (let 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 pagesfunction findPages(arr,n,m){    let 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 (let i = 0; i < n; i++)        sum += arr[i];       // initialize start as 0 pages and end as    // total pages    let start = 0, end = sum;    let result = Number.MAX_VALUE;       // traverse until start <= end    while (start <= end)    {        // check if it is possible to distribute        // books by using mid as current minimum        let mid =Math.floor( (start + end) / 2);        if (isPossible(arr, n, m, mid))        {            // if yes then find the minimum distribution            result = Math.min(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 Methodlet arr=[12, 34, 67, 90];let m = 2; //No. of studentsdocument.write("Minimum number of pages = " +                          findPages(arr, arr.length, m));   // This code is contributed by patel2127</script>
Output :  
Minimum number of pages = 113
Time Complexity: O(N*log (M – max)), where N is the number of different books , max denotes the maximum number of pages from all the books and M denotes the sum of number of pages of all different booksAuxiliary Space: O(1)
This article is contributed by Sahil Chhabra (akku). If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
vt_m
Sach_Code
mohit kumar 29
patel2127
smack
pushpeshrajdx01
adityakumar129
anshulpro27
Binary Search
Google
Divide and Conquer
Searching
Google
Searching
Divide and Conquer
Binary Search
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.