给定 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 现场工作专业课程和学生竞争性编程现场课程。