Sunday, November 17, 2024
Google search engine
HomeLanguagesDynamic ProgrammingDivide the array in K segments such that the sum of minimums...

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

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:
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++




// 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 minimums
int 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 Code
int 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




// 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


Python3




# Python 3 program to find the sum of
# the minimum of all the segments
MAX = 10
 
# Function to maximize the
# sum of the minimums
def 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 Code
if __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#




// C# program to find the sum of
// the minimum of all the segments
using 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


Javascript




<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>


Output

13

Time Complexity: O(N * N * K) 
Auxiliary Space: O(N * K)

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments