Given an array arr[] consisting of N integers and an integer D, the task is to find the least integer T such that the entire array can be partitioned into at most D subarrays from the given array with sum atmost T.
Examples:
Input: D = 5, arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Output: 15
Explanation:
If T = 15, then 5 subarrays {{1, 2, 3, 4, 5}, {6, 7}, {8}, {9}, {10}}Input: D = 2, arr[] = {1, 1, 1, 1, 1}
Output: 3
Explanation:
If T = 3, then the 2 partitions are {{1, 1, 1}, {1, 1}}
Naive Approach: The idea is to check for all possible values of T in the range [max(element), sum(element)] whether it is possible to have at most D partition.
Time Complexity: O( N*R )
Auxiliary Space: O(1)
Efficient Approach: The idea is to use Binary search to optimize the above approach. Follow the steps below to solve the problem:
- Consider T in the range R = [ max(element), sum(element) ].
- If median T can generate at most D partitions, then check for a median lesser than T.
- Otherwise, check for a median greater than the current median T.
- Return the possible value of T at the end.
Below is the implementation of the above approach:
// C++ Program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to check if the array // can be partitioned into atmost d // subarray with sum atmost T bool possible( int T, int arr[], int n, int d)
{ // Initial partition
int partition = 1;
// Current sum
int total = 0;
for ( int i = 0; i < n; i++) {
total = total + arr[i];
// If current sum exceeds T
if (total > T) {
// Create a new partition
partition = partition + 1;
total = arr[i];
// If count of partitions
// exceed d
if (partition > d) {
return false ;
}
}
}
return true ;
} // Function to find the minimum // possible value of T void calcT( int n, int d, int arr[])
{ // Stores the maximum and
// total sum of elements
int mx = -1, sum = 0;
for ( int i = 0; i < n; i++) {
// Maximum element
mx = max(mx, arr[i]);
// Sum of all elements
sum = sum + arr[i];
}
int lb = mx;
int ub = sum;
while (lb < ub) {
// Calculate median T
int T_mid = lb + (ub - lb) / 2;
// If atmost D partitions possible
if (possible(T_mid, arr, n, d) == true ) {
// Check for smaller T
ub = T_mid;
}
// Otherwise
else {
// Check for larger T
lb = T_mid + 1;
}
}
// Print the minimum T required
cout << lb << endl;
} // Driver Code int main()
{ int d = 2;
int arr[] = { 1, 1, 1, 1, 1 };
int n = sizeof arr / sizeof arr[0];
// Function call
calcT(n, d, arr);
return 0;
} |
// Java program for the above approach import java.util.*;
import java.io.*;
class GFG{
// Function to check if the array // can be partitioned into atmost d // subarray with sum atmost T public static boolean possible( int T, int arr[],
int n, int d)
{ // Initial partition
int partition = 1 ;
// Current sum
int total = 0 ;
for ( int i = 0 ; i < n; i++)
{
total = total + arr[i];
// If current sum exceeds T
if (total > T)
{
// Create a new partition
partition = partition + 1 ;
total = arr[i];
// If count of partitions
// exceed d
if (partition > d)
{
return false ;
}
}
}
return true ;
} // Function to find the minimum // possible value of T public static void calcT( int n, int d,
int arr[])
{ // Stores the maximum and
// total sum of elements
int mx = - 1 , sum = 0 ;
for ( int i = 0 ; i < n; i++)
{
// Maximum element
mx = Math.max(mx, arr[i]);
// Sum of all elements
sum = sum + arr[i];
}
int lb = mx;
int ub = sum;
while (lb < ub)
{
// Calculate median T
int T_mid = lb + (ub - lb) / 2 ;
// If atmost D partitions possible
if (possible(T_mid, arr, n, d) == true )
{
// Check for smaller T
ub = T_mid;
}
// Otherwise
else
{
// Check for larger T
lb = T_mid + 1 ;
}
}
// Print the minimum T required
System.out.println(lb);
} // Driver code public static void main(String args[])
{ int d = 2 ;
int arr[] = { 1 , 1 , 1 , 1 , 1 };
int n = arr.length;
// Function call
calcT(n, d, arr);
} } // This code is contributed by decoding |
# Python3 program for the above approach # Function to check if the array # can be partitioned into atmost d # subarray with sum atmost T def possible(T, arr, n, d):
# Initial partition
partition = 1 ;
# Current sum
total = 0 ;
for i in range (n):
total = total + arr[i];
# If current sum exceeds T
if (total > T):
# Create a new partition
partition = partition + 1 ;
total = arr[i];
# If count of partitions
# exceed d
if (partition > d):
return False ;
return True ;
# Function to find the minimum # possible value of T def calcT(n, d, arr):
# Stores the maximum and
# total sum of elements
mx = - 1 ; sum = 0 ;
for i in range (n):
# Maximum element
mx = max (mx, arr[i]);
# Sum of all elements
sum = sum + arr[i];
lb = mx;
ub = sum ;
while (lb < ub):
# Calculate median T
T_mid = lb + (ub - lb) / / 2 ;
# If atmost D partitions possible
if (possible(T_mid, arr, n, d) = = True ):
# Check for smaller T
ub = T_mid;
# Otherwise
else :
# Check for larger T
lb = T_mid + 1 ;
# Print the minimum T required
print (lb);
# Driver code if __name__ = = '__main__' :
d = 2 ;
arr = [ 1 , 1 , 1 , 1 , 1 ];
n = len (arr);
# Function call
calcT(n, d, arr);
# This code is contributed by Rajput-Ji |
// C# program for the above approach using System;
class GFG{
// Function to check if the array // can be partitioned into atmost d // subarray with sum atmost T public static bool possible( int T, int []arr,
int n, int d)
{ // Initial partition
int partition = 1;
// Current sum
int total = 0;
for ( int i = 0; i < n; i++)
{
total = total + arr[i];
// If current sum exceeds T
if (total > T)
{
// Create a new partition
partition = partition + 1;
total = arr[i];
// If count of partitions
// exceed d
if (partition > d)
{
return false ;
}
}
}
return true ;
} // Function to find the minimum // possible value of T public static void calcT( int n, int d,
int []arr)
{ // Stores the maximum and
// total sum of elements
int mx = -1, sum = 0;
for ( int i = 0; i < n; i++)
{
// Maximum element
mx = Math.Max(mx, arr[i]);
// Sum of all elements
sum = sum + arr[i];
}
int lb = mx;
int ub = sum;
while (lb < ub)
{
// Calculate median T
int T_mid = lb + (ub - lb) / 2;
// If atmost D partitions possible
if (possible(T_mid, arr, n, d) == true )
{
// Check for smaller T
ub = T_mid;
}
// Otherwise
else
{
// Check for larger T
lb = T_mid + 1;
}
}
// Print the minimum T required
Console.WriteLine(lb);
} // Driver code public static void Main(String []args)
{ int d = 2;
int []arr = { 1, 1, 1, 1, 1 };
int n = arr.Length;
// Function call
calcT(n, d, arr);
} } // This code is contributed by 29AjayKumar |
<script> // JavaScript program for the // above approach // Function to check if the array // can be partitioned into atmost d // subarray with sum atmost T function possible(T, arr,
n, d)
{ // Initial partition
let partition = 1;
// Current sum
let total = 0;
for (let i = 0; i < n; i++)
{
total = total + arr[i];
// If current sum exceeds T
if (total > T)
{
// Create a new partition
partition = partition + 1;
total = arr[i];
// If count of partitions
// exceed d
if (partition > d)
{
return false ;
}
}
}
return true ;
} // Function to find the minimum // possible value of T function calcT(n, d, arr)
{ // Stores the maximum and
// total sum of elements
let mx = -1, sum = 0;
for (let i = 0; i < n; i++)
{
// Maximum element
mx = Math.max(mx, arr[i]);
// Sum of all elements
sum = sum + arr[i];
}
let lb = mx;
let ub = sum;
while (lb < ub)
{
// Calculate median T
let T_mid = lb + (ub - lb) / 2;
// If atmost D partitions possible
if (possible(T_mid, arr, n, d) == true )
{
// Check for smaller T
ub = T_mid;
}
// Otherwise
else
{
// Check for larger T
lb = T_mid + 1;
}
}
// Print the minimum T required
document.write(lb);
} // Driver Code let d = 2;
let arr = [ 1, 1, 1, 1, 1 ];
let n = arr.length;
// Function call
calcT(n, d, arr);
</script> |
3
Time complexity: O( N*log(sum) )
Auxiliary Space: O(1)