Partition Array for Maximum Sum

Updated on 01 July, 2025
Partition Array for Maximum Sum header image

Problem Statement

The task involves transforming a given integer array by partitioning it into contiguous subarrays where each is of length at most k. After partitioning, every element of a subarray is replaced by the maximum element of that subarray. The goal is to calculate the sum of the transformed array and return this maximum possible sum. This optimizes the subarray partitions to achieve the highest aggregate sum in the transformed array, ensuring that the result fits within a 32-bit integer size.

Examples

Example 1

Input:

arr = [1,15,7,9,2,5,10], k = 3

Output:

84

Explanation:

arr becomes [15,15,15,9,10,10,10]

Example 2

Input:

arr = [1,4,1,5,7,3,6,1,9,9,3], k = 4

Output:

83

Example 3

Input:

arr = [1], k = 1

Output:

1

Constraints

  • 1 <= arr.length <= 500
  • 0 <= arr[i] <= 109
  • 1 <= k <= arr.length

Approach and Intuition

The main challenge is to find an optimal way to partition the array such that the sum of the maximum values from each partitioned subarray is maximized. Here’s a step-by-step breakdown of how one might approach this problem, using the examples provided as illustrations:

  1. Understanding the dynamics with k:

    • When k is 1, each element forms a subarray by itself, and the solution is simply the sum of all the elements.
    • When k is equal to the length of the array, the entire array is one subarray, and the solution is the maximum value of the array multiplied by the array's length.
  2. Progressive Evaluation Using Dynamic Programming:

    • Set up a DP array dp where dp[i] will hold the maximum possible sum of the array up to the i-th element.
    • For each element i in the array:
      • Evaluate different subarray sizes that could end at i, ranging from 1 to k.
      • For each subarray size, calculate the sum if this subarray is turned into a subarray with all elements being the maximum value found in this subarray.
      • Use previous computed results from the dp array to accumulate the potential maximum sum up to index i.
  3. Iterative Calculation:

    • For each position i in the array arr, iterate backwards up to i-k (or the start of the array, whichever comes first) to check possible positions j where a partition could end.
    • Calculate the maximum element between j and i during this iteration.
    • Update the dp array as: dp[i] = max(dp[i], dp[j-1] + max_element * (i-j+1)).
    • The value of dp[arr.length-1] after the loop ends gives the required result.

Extended Example Clarification

* **Example 1 (arr = [1,15,7,9,2,5,10], k = 3)**:
    * Initial larger partitions will revolve around picking the largest possible segments where the local maximum affects the most numbers, e.g., transforming the first three numbers all to 15.
* **Example 2 (arr = [1,4,1,5,7,3,6,1,9,9,3], k = 4)**:
    * More partitions possible, the approach tries to make partitions around larger numbers like 7, 9 to maximize the sum.

By carefully partitioning the array considering local maxima and optimal subarray lengths as dictated by k, we can dynamically program our way to the best solution that maximizes the array's sum under the given conditions.

Solutions

  • C++
  • Java
cpp
class Solution {
public:
    int maximumSumWithPartitions(vector<int>& array, int maxLen) {
        int len = array.size();
    
        int memo[len + 1];
        memset(memo, 0, sizeof(memo));
            
        for (int startIdx = len - 1; startIdx >= 0; startIdx--) {
            int maxVal = 0;
            int limit = min(len, startIdx + maxLen);
    
            for (int j = startIdx; j < limit; j++) {
                maxVal = max(maxVal, array[j]);
                // Compare and store the maximum sum possible with partitioning.
                memo[startIdx] = max(memo[startIdx], memo[j + 1] + maxVal * (j - startIdx + 1));
            }
        }
        return memo[0];
    }
};

The C++ solution provided addresses the challenge of determining the maximum sum obtained from partitioning an array with partitions restricted by a specified maximum length. The implementation primarily functions through dynamic programming to keep track and calculate the optimal partitions:

  • Declare and initialized a memo array to cache results for subproblems, where each index represents the maximum sum from that start index to the end of the array.
  • Iterate over the array elements from end to start to fill the memo dynamically, allowing calculation based on previously computed results for subarrays.
  • During each iteration for a position startIdx, another loop explores potential partitions up to the defined maximum length (maxLen). Keep track of the maximum value (maxVal) in the current partition to update the memo for that starting index.
  • The inner loop calculates the score of possible partitions from startIdx and updates the maximum sum for this position, based on earlier computed results and current partition values.
  • Finally, return the value in memo[0] which holds the maximum sum achievable for the entire array using valid partitions.

This dynamic approach ensures all possibilities are correctly evaluated by breaking down the problem into sub-parts, and efficiently using previously stored information to solve each subproblem, leading to an overall optimal solution for the original problem.

java
class Solution {
    public int maximumPartitionSum(int[] array, int maxLen) {
        int arraySize = array.length;
    
        int[] dpArray = new int[arraySize + 1];
        Arrays.fill(dpArray, 0);
    
        for (int idx = arraySize - 1; idx >= 0; idx--) {
            int maxElement = 0;
            int endLimit = Math.min(arraySize, idx + maxLen);
    
            for (int pointer = idx; pointer < endLimit; pointer++) {
                maxElement = Math.max(maxElement, array[pointer]);
                dpArray[idx] = Math.max(dpArray[idx], dpArray[pointer + 1] + maxElement * (pointer - idx + 1));
            }
        }
        return dpArray[0];
    }
}

This Java solution tackles the problem of finding the maximum sum partition of an array with constraints on the maximum length of each partition.

  • Begin by defining the maximumPartitionSum method which takes an array and an integer maxLen representing the maximum length of a partition.
  • Initialize arraySize to store the length of the provided array.
  • Create a dynamic programming array dpArray with an additional space to handle index offsets smoothly. Initialize all elements to zero using Arrays.fill(dpArray, 0).
  • Process the array from the end to the beginning using a loop. This reverse traversal helps in solving subproblems that depend on the results of the next elements.
  • For each element in the array, calculate the possible maximum values for subsequences starting at the current index and having lengths up to maxLen.
  • Inside the loop, maintain a variable maxElement to track the maximum value found in the current subarray. It helps in calculating the potential maximum sum for the partition that extends up to maxLen elements from the current index.
  • Use another loop nested inside the main loop to explore each partition length and update the dpArray with the maximum possible sum calculated using the formula dpArray[pointer + 1] + maxElement * (pointer - idx + 1).
  • After iterating through all possible partitions and lengths, the first element of dpArray will hold the maximum sum achievable under the given constraints.

This algorithm efficiently calculates the solution by utilizing dynamic programming principles, ensuring that each sub-problem is solved only once and using previous solutions to construct the answer for the entire problem.

Comments

No comments yet.