Divide the array in K segments such that the sum of minimums is maximized

26 May, 2022
Given an array a of size N and an integer K, the task is to divide the array into K segments such that sum of the minimum of K segments is maximized. Examples:  
Input: a[] = {5, 7, 4, 2, 8, 1, 6}, K = 3 Output: 7 Divide the array at indexes 0 and 1. Then the segments are {5}, {7}, {4, 2, 8, 1, 6}. Sum of the minimum is 5 + 7 + 1 = 13 Input: a[] = {6, 5, 3, 8, 9, 10, 4, 7, 10}, K = 4 Output: 27 
Approach: The problem can be solved using Dynamic Programming. Try all the possible partitions that are possible using recursion. Let dp[i][k] be the maximum sum of minimums till index i with k partitions. Hence the possible states will be partition at every index from the index i till n. The maximum sum of minimums of all those states will be our answer. After writing this recurrence, we can use memoization. 
Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ program to find the sum of// the minimum of all the segments#include <bits/stdc++.h>using namespace std;const int MAX = 10; // Function to maximize the sum of the minimumsint maximizeSum(int a[], int n, int ind,                int k, int dp[MAX][MAX]){     // If k segments have been divided    if (k == 0) {        // If we are at the end        if (ind == n)            return 0;         // If we donot reach the end        // then return a negative number        // that cannot be the sum        else            return -1e9;    }     // If at the end but    // k segments are not formed    else if (ind == n)        return -1e9;     // If the state has not been visited yet    else if (dp[ind][k] != -1)        return dp[ind][k];     // If the state has not been visited    else {        int ans = 0;         // Get the minimum element in the segment        int mini = a[ind];         // Iterate and try to break at every index        // and create a segment        for (int i = ind; i < n; i++) {             // Find the minimum element in the segment            mini = min(mini, a[i]);             // Find the sum of all the segments trying all            // the possible combinations            ans = max(ans, maximizeSum(              a, n, i + 1, k - 1, dp) + mini);        }         // Return the answer by        // memoizing it        return dp[ind][k] = ans;    }} // Driver Codeint main(){    int a[] = { 5, 7, 4, 2, 8, 1, 6 };    int k = 3;    int n = sizeof(a) / sizeof(a[0]);     // Initialize dp array with -1    int dp[MAX][MAX];    memset(dp, -1, sizeof dp);     cout << maximizeSum(a, n, 0, k, dp);     return 0;}
// Java program to find the sum of// the minimum of all the segments class GFG{     static int MAX = 10;     // Function to maximize the    // sum of the minimums    public static int maximizeSum(              int[] a, int n, int ind,                 int k, int[][] dp)    {        // If k segments have been divided        if (k == 0)        {            // If we are at the end            if (ind == n)                return 0;             // If we donot reach the end            // then return a negative number            // that cannot be the sum            else                return -1000000000;        }         // If at the end but        // k segments are not formed        else if (ind == n)            return -1000000000;         // If the state has not        // been visited yet        else if (dp[ind][k] != -1)            return dp[ind][k];         // If the state has        // not been visited        else        {            int ans = 0;             // Get the minimum            // element in the segment            int mini = a[ind];             // Iterate and try to break            // at every index            // and create a segment            for (int i = ind; i < n; i++)            {                 // Find the minimum element                // in the segment                mini = Math.min(mini, a[i]);                 // Find the sum of all the                // segments trying all                // the possible combinations                ans = Math.max(ans,                     maximizeSum(a, n, i + 1,                           k - 1, dp) + mini);            }             // Return the answer by            // memoizing it            return dp[ind][k] = ans;        }    }     // Driver Code    public static void main(String[] args)    {        int[] a = { 5, 7, 4, 2, 8, 1, 6 };        int k = 3;        int n = a.length;         // Initialize dp array with -1        int[][] dp = new int[MAX][MAX];        for (int i = 0; i < MAX; i++)        {            for (int j = 0; j < MAX; j++)                dp[i][j] = -1;        }         System.out.println(          maximizeSum(a, n, 0, k, dp));    }} // This code is contributed by// sanjeev2552
# Python 3 program to find the sum of# the minimum of all the segmentsMAX = 10 # Function to maximize the# sum of the minimumsdef maximizeSum(a,n, ind, k, dp):    # If k segments have been divided    if (k == 0):        # If we are at the end        if (ind == n):            return 0         # If we donot reach the end        # then return a negative number        # that cannot be the sum        else:            return -1e9     # If at the end but    # k segments are not formed    elif (ind == n):        return -1e9     # If the state has been visited already    elif (dp[ind][k] != -1):        return dp[ind][k]     # If the state has not been visited    else:        ans = 0         # Get the minimum element        # in the segment        mini = a[ind]         # Iterate and try to break        # at every index        # and create a segment        for i in range(ind,n,1):            # Find the minimum element            # in the segment            mini = min(mini, a[i])             # Find the sum of all the            # segments trying all            # the possible combinations            ans = max(ans, maximizeSum(\             a, n, i + 1, k - 1, dp) + mini)         # Return the answer by        # memoizing it        dp[ind][k] = ans        return ans         # Driver Codeif __name__ == '__main__':    a = [5, 7, 4, 2, 1, 6]    k = 3    n = len(a)     # Initialize dp array with -1    dp = [[-1 for i in range(MAX)]\          for j in range(MAX)]     print(maximizeSum(a, n, 0, k, dp)) # This code is contributed by# Surendra_Gangwar
// C# program to find the sum of// the minimum of all the segmentsusing System;     class GFG{    static int MAX = 10;     // Function to maximize the sum of the minimums    public static int maximizeSum(             int[] a, int n, int ind,                  int k, int[] dp)    {        // If k segments have been divided        if (k == 0)        {            // If we are at the end            if (ind == n)                return 0;             // If we donot reach the end            // then return a negative number            // that cannot be the sum            else                return -1000000000;        }         // If at the end but        // k segments are not formed        else if (ind == n)            return -1000000000;         // If the state has not        // been visited yet        else if (dp[ind, k] != -1)            return dp[ind, k];         // If the state has not been visited        else        {            int ans = 0;             // Get the minimum element            // in the segment            int mini = a[ind];             // Iterate and try to break            // at every index            // and create a segment            for (int i = ind; i < n; i++)            {                 // Find the minimum element                // in the segment                mini = Math.Min(mini, a[i]);                 // Find the sum of all the                // segments trying all                // the possible combinations                ans = Math.Max(ans,                      maximizeSum(a, n, i + 1,                           k - 1, dp) + mini);            }             // Return the answer by            // memoizing it            return dp[ind,k] = ans;        }    }     // Driver Code    public static void Main(String[] args)    {        int[] a = { 5, 7, 4, 2, 8, 1, 6 };        int k = 3;        int n = a.Length;         // Initialize dp array with -1        int[,] dp = new int[MAX, MAX];        for (int i = 0; i < MAX; i++)        {            for (int j = 0; j < MAX; j++)                dp[i, j] = -1;        }         Console.WriteLine(          maximizeSum(a, n, 0, k, dp));    }} // This code is contributed by 29AjayKumar
<script> // JavaScript program to find the sum of// the minimum of all the segments    var MAX = 10;     // Function to maximize the    // sum of the minimums    function maximizeSum(a , n , ind , k,  dp)    {        // If k segments have been divided        if (k == 0) {            // If we are at the end            if (ind == n)                return 0;             // If we donot reach the end            // then return a negative number            // that cannot be the sum            else                return -1000000000;        }         // If at the end but        // k segments are not formed        else if (ind == n)            return -1000000000;         // If the state has not        // been visited yet        else if (dp[ind][k] != -1)            return dp[ind][k];         // If the state has        // not been visited        else {            var ans = 0;             // Get the minimum            // element in the segment            var mini = a[ind];             // Iterate and try to break            // at every index            // and create a segment            for (i = ind; i < n; i++) {                 // Find the minimum element                // in the segment                mini = Math.min(mini, a[i]);                 // Find the sum of all the                // segments trying all                // the possible combinations                ans = Math.max(ans,                maximizeSum(a, n, i + 1, k - 1, dp) + mini);            }             // Return the answer by            // memoizing it            return dp[ind][k] = ans;        }    }     // Driver Code             var a = [ 5, 7, 4, 2, 8, 1, 6 ];        var k = 3;        var n = a.length;         // Initialize dp array with -1        var dp =        Array(MAX).fill().map(()=>Array(MAX).fill(0));        for (var i = 0; i < MAX; i++) {            for (j = 0; j < MAX; j++)                dp[i][j] = -1;        }         document.write(maximizeSum(a, n, 0, k, dp)); // This code contributed by Rajput-Ji </script>
13
Time Complexity: O(N * N * K) Auxiliary Space: O(N * K)
SURENDRA_GANGWAR
sanjeev2552
29AjayKumar
shubhamjain0594
Rajput-Ji
sumitgumber28
jainlovely450
Arrays
Dynamic Programming
Recursion
Arrays
Dynamic Programming
Recursion
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.