Partition Array into Atmost K Length Segments for Maximum Sum

Last Updated : 7 Jun, 2026

Given an integer array arr[] and an integer k, partition the array into contiguous subarrays such that each subarray has a length of at most k. After partitioning, replace every element in each subarray with the maximum element present in that subarray.

Compute the maximum possible sum of the array after performing this operation.

Input: arr = [4, 1, 2, 3], k = 2
Output: 14
Explanation: One optimal partition is [4, 1] and [2, 3]. Therefore, the maximum possible sum will be 4 + 4 + 3 + 3 = 14.

Input: arr[] = [2, 2], k = 1
Output: 4
Explanation: The array is partitioned as [2] and [2]. Hence, the sum is 2 + 2 = 4.

Input: arr[] = [4, 6, 1, 1, 1], k = 2
Output: 18
Explanation: One optimal partition is [4], [6, 1] and [1, 1], Therefore, the maximum possible sum will be 4 + 6 + 6 + 1 + 1 = 18.

Try It Yourself
redirect icon

[Naive Approach] - Using Recursion - O(k^n) Time and O(n) Space

The idea is to try all possible partitions starting from the current index. For each partition of length from 1 to k, we keep track of the maximum element in that partition. Since every element in the partition is replaced by this maximum value, its contribution becomes maximum element × partition length. We then recursively solve the remaining array and take the maximum sum among all possible partition choices.

C++
#include<iostream>
#include<vector>
using namespace std;

// Returns the maximum sum obtainable starting from index i
int maxSumRec(vector<int>& arr, int i, int k) {
    int n = arr.size();

    // No elements left to partition
    if (i == n)
        return 0;

    int maxVal = 0;
    int ans = 0;

    // Try all valid partition lengths starting at i
    for (int j = i; j < min(n, i + k); j++) {
        maxVal = max(maxVal, arr[j]);

        int len = j - i + 1;
        ans = max(ans, maxVal * len + maxSumRec(arr, j + 1, k));
    }

    return ans;
}

// Returns the maximum possible sum after partitioning arr[]
int maxPartitionSum(vector<int>& arr, int k) {
    return maxSumRec(arr, 0, k);
}

int main() {
    vector<int> arr = {4, 1, 2, 3};
    int k = 2;

    cout << maxPartitionSum(arr, k) << endl;
    return 0;
}
Java
public class GfG {

    // Returns the maximum sum obtainable starting from index i
    static int maxSumRec(int[] arr, int i, int k) {
        int n = arr.length;
        // No elements left to partition
        if (i == n)
            return 0;
        int maxVal = 0;
        int ans = 0;
        // Try all valid partition lengths starting at i
        for (int j = i; j < Math.min(n, i + k); j++) {
            maxVal = Math.max(maxVal, arr[j]);
            int len = j - i + 1;
            ans = Math.max(ans, maxVal * len + maxSumRec(arr, j + 1, k));
        }
        return ans;
    }

    // Returns the maximum possible sum after partitioning arr[]
    static int maxPartitionSum(int[] arr, int k) {
        return maxSumRec(arr, 0, k);
    }

    public static void main(String[] args) {
        int[] arr = {4, 1, 2, 3};
        int k = 2;
        System.out.println(maxPartitionSum(arr, k));
    }
}
Python
# Returns the maximum sum obtainable starting from index i
def maxSumRec(arr, i, k):
    n = len(arr)
    # No elements left to partition
    if i == n:
        return 0
    maxVal = 0
    ans = 0
    # Try all valid partition lengths starting at i
    for j in range(i, min(n, i + k)):
        maxVal = max(maxVal, arr[j])
        length = j - i + 1
        ans = max(ans, maxVal * length + maxSumRec(arr, j + 1, k))
    return ans

# Returns the maximum possible sum after partitioning arr[]
def maxPartitionSum(arr, k):
    return maxSumRec(arr, 0, k)

if __name__ == "__main__":
    arr = [4, 1, 2, 3]
    k = 2
    print(maxPartitionSum(arr, k))
C#
using System;

class GfG {

    // Returns the maximum sum obtainable starting from index i
    static int MaxSumRec(int[] arr, int i, int k) {
        int n = arr.Length;
        // No elements left to partition
        if (i == n)
            return 0;
        int maxVal = 0;
        int ans = 0;
        // Try all valid partition lengths starting at i
        for (int j = i; j < Math.Min(n, i + k); j++) {
            maxVal = Math.Max(maxVal, arr[j]);
            int len = j - i + 1;
            ans = Math.Max(ans, maxVal * len + MaxSumRec(arr, j + 1, k));
        }
        return ans;
    }

    // Returns the maximum possible sum after partitioning arr[]
    static int MaxPartitionSum(int[] arr, int k) {
        return MaxSumRec(arr, 0, k);
    }

    static void Main() {
        int[] arr = {4, 1, 2, 3};
        int k = 2;
        Console.WriteLine(MaxPartitionSum(arr, k));
    }
}
JavaScript
// Returns the maximum sum obtainable starting from index i
function maxSumRec(arr, i, k) {
    const n = arr.length;
    // No elements left to partition
    if (i === n)
        return 0;
    let maxVal = 0;
    let ans = 0;
    // Try all valid partition lengths starting at i
    for (let j = i; j < Math.min(n, i + k); j++) {
        maxVal = Math.max(maxVal, arr[j]);
        const len = j - i + 1;
        ans = Math.max(ans, maxVal * len + maxSumRec(arr, j + 1, k));
    }
    return ans;
}

// Returns the maximum possible sum after partitioning arr[]
function maxPartitionSum(arr, k) {
    return maxSumRec(arr, 0, k);
}


// Driver code
const arr = [4, 1, 2, 3];
const k = 2;
console.log(maxPartitionSum(arr, k));

Output
14

[Expected Approach] - Using Dynamic Programming – O(n^2) Time and O(n) Space

The recursive solution recalculates many subproblems multiple times. This can be optimized using Dynamic Programming. Define a DP array dp[] where dp[i] represents the maximum sum achievable using the first i elements. For each position i, consider partitions ending at index i - 1 with size at most k. While expanding the partition backwards, maintain the maximum element in the partition and update the best possible value.

Steps:

  1. Create a DP array dp of size n + 1, where dp[i] represents the maximum sum obtainable using the first i elements.
  2. Iterate through each position i from 1 to n.
  3. For every i, try all possible partition sizes from 1 to k that end at index i - 1.
  4. While expanding the partition backwards, maintain the maximum element (curmax) in the current partition.
  5. The contribution of the current partition is: curmax × partition_length
  6. Combine this contribution with the best answer before the partition: dp[i - partition_length]
  7. Store the maximum value among all valid partition choices in dp[i].
  8. The final answer is dp[n].
C++
#include<iostream>
#include <vector>
using namespace std;

int maxPartitionSum(vector<int>& arr, int k) {

    int n = arr.size();

    // dp[i] = maximum sum that can be obtained
    // using the first i elements of the array
    vector<int> dp(n + 1, 0);

    for (int i = 1; i <= n; i++) {

        int curmax = 0;
        int best = 0;

        // Try all possible partition lengths ending at index (i - 1)
        // with size from 1 to k
        for (int j = 1; j <= k && i - j >= 0; j++) {

            // Maximum element in the current partition
            curmax = max(curmax, arr[i - j]);

            // Contribution of current partition:
            // (partition length) * (maximum element in partition)
            best = max(best, dp[i - j] + curmax * j);
        }

        // Store the best answer for first i elements
        dp[i] = best;
    }

    return dp[n];
}

int main() {

    vector<int> arr = {4, 1, 2, 3};
    int k = 2;

    cout << maxPartitionSum(arr, k);

    return 0;
}
Java
public class Main {

    static int maxPartitionSum(int[] arr, int k) {
        int n = arr.length;
        
        // dp[i] = maximum sum that can be obtained
        // using the first i elements of the array
        int[] dp = new int[n + 1];

        for (int i = 1; i <= n; i++) {
            int curmax = 0;
            int best = 0;
            
            // Try all possible partition lengths ending at index (i - 1)
            // with size from 1 to k
            for (int j = 1; j <= k && i - j >= 0; j++) {
                
                // Maximum element in the current partition
                curmax = Math.max(curmax, arr[i - j]);
                
                // Contribution of current partition:
                // (partition length) * (maximum element in partition)
                best = Math.max(best, dp[i - j] + curmax * j);
            }
            
            // Store the best answer for first i elements
            dp[i] = best;
        }
        return dp[n];
    }

    public static void main(String[] args) {
        int[] arr = {4, 1, 2, 3};
        int k = 2;
        System.out.println(maxPartitionSum(arr, k));
    }
}
Python
def maxPartitionSum(arr, k):
    n = len(arr)
    
    # dp[i] = maximum sum that can be obtained
    # using the first i elements of the array
    dp = [0] * (n + 1)

    for i in range(1, n + 1):
        curmax = 0
        best = 0
        
        # Try all possible partition lengths ending at index (i - 1)
        # with size from 1 to k
        j = 1
        while j <= k and i - j >= 0:
            
            # Maximum element in the current partition
            curmax = max(curmax, arr[i - j])
            
            # Contribution of current partition:
            # (partition length) * (maximum element in partition)
            best = max(best, dp[i - j] + curmax * j)
            j += 1
            
        # Store the best answer for first i elements
        dp[i] = best

    return dp[n]

if __name__ == "__main__":
    arr = [4, 1, 2, 3]
    k = 2
    print(maxPartitionSum(arr, k))
C#
using System;

class GfG {

    static int MaxPartitionSum(int[] arr, int k) {
        int n = arr.Length;
        
        // dp[i] = maximum sum that can be obtained
        // using the first i elements of the array
        int[] dp = new int[n + 1];

        for (int i = 1; i <= n; i++) {
            int curmax = 0;
            int best = 0;
            
            // Try all possible partition lengths ending at index (i - 1)
            // with size from 1 to k
            for (int j = 1; j <= k && i - j >= 0; j++) {
                
                // Maximum element in the current partition
                curmax = Math.Max(curmax, arr[i - j]);
                
                // Contribution of current partition:
                // (partition length) * (maximum element in partition)
                best = Math.Max(best, dp[i - j] + curmax * j);
            }
            
            // Store the best answer for first i elements
            dp[i] = best;
        }
        return dp[n];
    }

    static void Main() {
        int[] arr = {4, 1, 2, 3};
        int k = 2;
        Console.WriteLine(MaxPartitionSum(arr, k));
    }
}
JavaScript
function maxPartitionSum(arr, k) {
    const n = arr.length;
    
    // dp[i] = maximum sum that can be obtained
    // using the first i elements of the array
    const dp = new Array(n + 1).fill(0);

    for (let i = 1; i <= n; i++) {
        let curmax = 0;
        let best = 0;
        
        // Try all possible partition lengths ending at index (i - 1)
        // with size from 1 to k
        for (let j = 1; j <= k && i - j >= 0; j++) {
            
            // Maximum element in the current partition
            curmax = Math.max(curmax, arr[i - j]);
            
            // Contribution of current partition:
            // (partition length) * (maximum element in partition)
            best = Math.max(best, dp[i - j] + curmax * j);
        }
        
        // Store the best answer for first i elements
        dp[i] = best;
    }
    return dp[n];
}

// Driver code
const arr = [4, 1, 2, 3];
const k = 2;
console.log(maxPartitionSum(arr, k));

Output
14
Comment