Minimum possible value T such that at most D Partitions of the Array having at most sum T is possible
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++
// 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
// 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
# 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#
// 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 |
Javascript
<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)
Please Login to comment...