Maximum average sum partition of an array
Last Updated :
20 Dec, 2022
Given an array, we partition a row of numbers A into at most K adjacent (non-empty) groups, then the score is the sum of the average of each group. What is the maximum score that can be scored?
Examples:
Input : A = { 9, 1, 2, 3, 9 }
K = 3
Output : 20
Explanation : We can partition A into [9], [1, 2, 3], [9]. The answer is 9 + (1 + 2 + 3) / 3 + 9 = 20.
We could have also partitioned A into [9, 1], [2], [3, 9]. That partition would lead to a score of 5 + 2 + 6 = 13, which is worse.
Input : A[] = { 1, 2, 3, 4, 5, 6, 7 }
K = 4
Output : 20.5
Explanation : We can partition A into [1, 2, 3, 4], [5], [6], [7]. The answer is 2.5 + 5 + 6 + 7 = 20.5.
A simple solution is to use recursion. An efficient solution is memorization where we keep the largest score upto k i.e. for 1, 2, 3... upto k;
Let memo[i][k] be the best score portioning A[i..n-1] into at most K parts. In the first group, we partition A[i..n-1] into A[i..j-1] and A[j..n-1], then our candidate partition has score average(i, j) + score(j, k-1)), where average(i, j) = (A[i] + A[i+1] + ... + A[j-1]) / (j - i). We take the highest score of these.
In total, our recursion in the general case is :
memo[n][k] = max(memo[n][k], score(memo, i, A, k-1) + average(i, j))
for all i from n-1 to 1 .
Implementation:
C++
// CPP program for maximum average sum partition
#include <bits/stdc++.h>
using namespace std;
#define MAX 1000
double memo[MAX][MAX];
// bottom up approach to calculate score
double score(int n, vector<int>& A, int k)
{
if (memo[n][k] > 0)
return memo[n][k];
double sum = 0;
for (int i = n - 1; i > 0; i--) {
sum += A[i];
memo[n][k] = max(memo[n][k], score(i, A, k - 1) +
sum / (n - i));
}
return memo[n][k];
}
double largestSumOfAverages(vector<int>& A, int K)
{
int n = A.size();
double sum = 0;
memset(memo, 0.0, sizeof(memo));
for (int i = 0; i < n; i++) {
sum += A[i];
// storing averages from starting to each i ;
memo[i + 1][1] = sum / (i + 1);
}
return score(n, A, K);
}
int main()
{
vector<int> A = { 9, 1, 2, 3, 9 };
int K = 3; // atmost partitioning size
cout << largestSumOfAverages(A, K) << endl;
return 0;
}
Java
// Java program for maximum average sum partition
import java.util.Arrays;
import java.util.Vector;
class GFG
{
static int MAX = 1000;
static double[][] memo = new double[MAX][MAX];
// bottom up approach to calculate score
public static double score(int n, Vector<Integer> A, int k)
{
if (memo[n][k] > 0)
return memo[n][k];
double sum = 0;
for (int i = n - 1; i > 0; i--)
{
sum += A.elementAt(i);
memo[n][k] = Math.max(memo[n][k],
score(i, A, k - 1) +
sum / (n - i));
}
return memo[n][k];
}
public static double largestSumOfAverages(Vector<Integer> A, int K)
{
int n = A.size();
double sum = 0;
for (int i = 0; i < memo.length; i++)
{
for (int j = 0; j < memo[i].length; j++)
memo[i][j] = 0.0;
}
for (int i = 0; i < n; i++)
{
sum += A.elementAt(i);
// storing averages from starting to each i ;
memo[i + 1][1] = sum / (i + 1);
}
return score(n, A, K);
}
// Driver code
public static void main(String[] args)
{
Vector<Integer> A = new Vector<>(Arrays.asList(9, 1, 2, 3, 9));
int K = 3;
System.out.println(largestSumOfAverages(A, K));
}
}
// This code is contributed by sanjeev2552
Python3
# Python3 program for maximum average sum partition
MAX = 1000
memo = [[0.0 for i in range(MAX)]
for i in range(MAX)]
# bottom up approach to calculate score
def score(n, A, k):
if (memo[n][k] > 0):
return memo[n][k]
sum = 0
i = n - 1
while(i > 0):
sum += A[i]
memo[n][k] = max(memo[n][k], score(i, A, k - 1) +
int(sum / (n - i)))
i -= 1
return memo[n][k]
def largestSumOfAverages(A, K):
n = len(A)
sum = 0
for i in range(n):
sum += A[i]
# storing averages from starting to each i ;
memo[i + 1][1] = int(sum / (i + 1))
return score(n, A, K)
# Driver Code
if __name__ == '__main__':
A = [9, 1, 2, 3, 9]
K = 3 # atmost partitioning size
print(largestSumOfAverages(A, K))
# This code is contributed by
# Surendra_Gangwar
C#
// C# program for maximum average sum partition
using System;
using System.Collections.Generic;
class GFG
{
static int MAX = 1000;
static double[,] memo = new double[MAX, MAX];
// bottom up approach to calculate score
public static double score(int n,
List<int> A, int k)
{
if (memo[n, k] > 0)
return memo[n, k];
double sum = 0;
for (int i = n - 1; i > 0; i--)
{
sum += A[i];
memo[n, k] = Math.Max(memo[n, k],
score(i, A, k - 1) +
sum / (n - i));
}
return memo[n, k];
}
public static double largestSumOfAverages(List<int> A,
int K)
{
int n = A.Count;
double sum = 0;
for (int i = 0;
i < memo.GetLength(0); i++)
{
for (int j = 0;
j < memo.GetLength(1); j++)
memo[i, j] = 0.0;
}
for (int i = 0; i < n; i++)
{
sum += A[i];
// storing averages from
// starting to each i;
memo[i + 1, 1] = sum / (i + 1);
}
return score(n, A, K);
}
// Driver code
public static void Main(String[] args)
{
int [] arr = {9, 1, 2, 3, 9};
List<int> A = new List<int>(arr);
int K = 3;
Console.WriteLine(largestSumOfAverages(A, K));
}
}
// This code is contributed by Rajput-Ji
JavaScript
<script>
// JavaScript program for maximum average sum partition
let MAX = 1000;
let memo = new Array(MAX).fill(0).map(() => new Array(MAX).fill(0));
// bottom up approach to calculate score
function score(n, A, k) {
if (memo[n][k] > 0)
return memo[n][k];
let sum = 0;
for (let i = n - 1; i > 0; i--) {
sum += A[i];
memo[n][k] = Math.max(memo[n][k], score(i, A, k - 1) +
sum / (n - i));
}
return memo[n][k];
}
function largestSumOfAverages(A, K) {
let n = A.length;
let sum = 0;
for (let i = 0; i < n; i++) {
sum += A[i];
// storing averages from starting to each i ;
memo[i + 1][1] = sum / (i + 1);
}
return score(n, A, K);
}
let A = [9, 1, 2, 3, 9];
let K = 3; // atmost partitioning size
document.write(largestSumOfAverages(A, K) + "<br>");
</script>
Above problem can now be easily understood as dynamic programming.
Let dp(i, k) be the best score partitioning A[i:j] into at most K parts. If the first group we partition A[i:j] into ends before j, then our candidate partition has score average(i, j) + dp(j, k-1)). Recursion in the general case is dp(i, k) = max(average(i, N), (average(i, j) + dp(j, k-1))). We can precompute the prefix sums for fast execution of out code.
Implementation:
C++
// CPP program for maximum average sum partition
#include <bits/stdc++.h>
using namespace std;
double largestSumOfAverages(vector<int>& A, int K)
{
int n = A.size();
// storing prefix sums
double pre_sum[n+1];
pre_sum[0] = 0;
for (int i = 0; i < n; i++)
pre_sum[i + 1] = pre_sum[i] + A[i];
// for each i to n storing averages
double dp[n] = {0};
double sum = 0;
for (int i = 0; i < n; i++)
dp[i] = (pre_sum[n] - pre_sum[i]) / (n - i);
for (int k = 0; k < K - 1; k++)
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
dp[i] = max(dp[i], (pre_sum[j] -
pre_sum[i]) / (j - i) + dp[j]);
return dp[0];
}
// Driver code
int main()
{
vector<int> A = { 9, 1, 2, 3, 9 };
int K = 3; // atmost partitioning size
cout << largestSumOfAverages(A, K) << endl;
return 0;
}
Java
// Java program for maximum average sum partition
import java.util.*;
class GFG
{
static double largestSumOfAverages(int[] A, int K)
{
int n = A.length;
// storing prefix sums
double []pre_sum = new double[n + 1];
pre_sum[0] = 0;
for (int i = 0; i < n; i++)
pre_sum[i + 1] = pre_sum[i] + A[i];
// for each i to n storing averages
double []dp = new double[n];
double sum = 0;
for (int i = 0; i < n; i++)
dp[i] = (pre_sum[n] - pre_sum[i]) / (n - i);
for (int k = 0; k < K - 1; k++)
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
dp[i] = Math.max(dp[i], (pre_sum[j] -
pre_sum[i]) / (j - i) + dp[j]);
return dp[0];
}
// Driver code
public static void main(String[] args)
{
int []A = { 9, 1, 2, 3, 9 };
int K = 3; // atmost partitioning size
System.out.println(largestSumOfAverages(A, K));
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python3 program for maximum average
# sum partition
def largestSumOfAverages(A, K):
n = len(A);
# storing prefix sums
pre_sum = [0] * (n + 1);
pre_sum[0] = 0;
for i in range(n):
pre_sum[i + 1] = pre_sum[i] + A[i];
# for each i to n storing averages
dp = [0] * n;
sum = 0;
for i in range(n):
dp[i] = (pre_sum[n] -
pre_sum[i]) / (n - i);
for k in range(K - 1):
for i in range(n):
for j in range(i + 1, n):
dp[i] = max(dp[i], (pre_sum[j] -
pre_sum[i]) /
(j - i) + dp[j]);
return int(dp[0]);
# Driver code
A = [ 9, 1, 2, 3, 9 ];
K = 3; # atmost partitioning size
print(largestSumOfAverages(A, K));
# This code is contributed by Rajput-Ji
C#
// C# program for maximum average sum partition
using System;
using System.Collections.Generic;
class GFG
{
static double largestSumOfAverages(int[] A,
int K)
{
int n = A.Length;
// storing prefix sums
double []pre_sum = new double[n + 1];
pre_sum[0] = 0;
for (int i = 0; i < n; i++)
pre_sum[i + 1] = pre_sum[i] + A[i];
// for each i to n storing averages
double []dp = new double[n];
for (int i = 0; i < n; i++)
dp[i] = (pre_sum[n] - pre_sum[i]) / (n - i);
for (int k = 0; k < K - 1; k++)
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
dp[i] = Math.Max(dp[i], (pre_sum[j] -
pre_sum[i]) / (j - i) + dp[j]);
return dp[0];
}
// Driver code
public static void Main(String[] args)
{
int []A = { 9, 1, 2, 3, 9 };
int K = 3; // atmost partitioning size
Console.WriteLine(largestSumOfAverages(A, K));
}
}
// This code is contributed by PrinciRaj1992
JavaScript
<script>
// javascript program for maximum average sum partition
function largestSumOfAverages(A , K) {
var n = A.length;
// storing prefix sums
var pre_sum = Array(n + 1).fill(-1);
pre_sum[0] = 0;
for (var i = 0; i < n; i++)
pre_sum[i + 1] = pre_sum[i] + A[i];
// for each i to n storing averages
var dp = Array(n).fill(-1);
var sum = 0;
for (var i = 0; i < n; i++)
dp[i] = (pre_sum[n] - pre_sum[i]) / (n - i);
for (k = 0; k < K - 1; k++)
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++)
dp[i] = Math.max(dp[i], (pre_sum[j] - pre_sum[i]) / (j - i) + dp[j]);
return dp[0];
}
// Driver code
var A = [ 9, 1, 2, 3, 9 ];
var K = 3; // atmost partitioning size
document.write(largestSumOfAverages(A, K));
// This code is contributed by umadevi9616
</script>
Time Complexity: O(n2*K)
Auxiliary Space: O(n)
Similar Reads
Maximum sum of i*arr[i] among all rotations of a given array
Given an integer array arr[] of size n. The task is to find the maximum value of the sum of the value of i * arr[i] where i varies from 0 to n-1. The only operation allowed is to rotate the array any number of times.Examples: Input: arr[] = [8, 3, 1, 2]Output: 29Explanation: Out of all the possible
13 min read
Partition an array such into maximum increasing segments
We are given an array of N integers, we need to partition the array into segments such that every element of a segment is greater than every element of previous segment. In other words, if we sort these individual segments, the whole array becomes sorted. We need to find a valid partition with maxim
7 min read
Optimizing K for Maximum Sum in Array
Given an array A[] of size N. You have to choose a number K between 1 and N (inclusive). Your score will be the sum of all the elements A[i] such that i is a multiple of K, the task is to find the minimum value of K with the maximum sum. Examples: Input: N = 2, A[] = {-3, 4}Output: 2Explanation: If
6 min read
Maximum sum of minimums of pairs in an array
Given an array arr[] of N integers where N is even, the task is to group the array elements in the pairs (X1, Y1), (X2, Y2), (X3, Y3), ... such that the sum min(X1, Y1) + min(X2, Y2) + min(X3, Y3) + ... is maximum.Examples: Input: arr[] = {1, 5, 3, 2} Output: 4 (1, 5) and (3, 2) -> 1 + 2 = 3 (1,
4 min read
Maximize sum of XOR of each element of Array with partition number
Given an array arr of positive integers of size N, the task is to split the array into 3 partitions, such that the sum of bitwise XOR of each element of the array with its partition number is maximum. Examples: Input: arr[] = { 2, 4, 7, 1, 8, 7, 2 }Output: First partition: 2 4 7 1 8Second partition:
9 min read
Maximum Subarray Sum of Alternate Parity
Given array A[] of size N. The Task for this problem is to find the maximum subarray (Subarrays are arrays within another array. Subarrays contain contiguous elements) sum such that adjacent elements of the subarray should have different parity. Examples: Input: A[] = {-1, 4, -1, 0, 5, -4} Output: 8
7 min read
Optimal partition of an array into four parts
Given an array of n non-negative integers. Choose three indices i.e. (0 <= index_1 <= index_ 2<= index_3 <= n) from the array to make four subsets such that the term sum(0, index_1) - sum(index_1, index_2) + sum(index_2, index_3) - sum(index_3, n) is maximum possible. Here, two indices s
9 min read
Count of permutations of an Array having maximum MEXs sum of prefix arrays
Given an array arr of size N, the task is to find the number of its permutations such that the sum of MEXs of its prefix arrays is maximum. Note: MEX of a set of integers is defined as the smallest non-negative integer that does not belong to this set. Example: Input: arr[] = {1, 0, 1}Output: 2Expla
10 min read
Largest pair sum in an array
Given an unsorted of distinct integers, find the largest pair sum in it. For example, the largest pair sum is 74. If there are less than 2 elements, then we need to return -1.Input : arr[] = {12, 34, 10, 6, 40}, Output : 74Input : arr[] = {10, 10, 10}, Output : 20Input arr[] = {10}, Output : -1[Naiv
10 min read
Maximum Sum of Array with given MEX
Given 3 integers N, K, and X, the task is to construct an array arr[] with the below conditions: Size of the array = NMEX of the array = KAll array elements should be at most XAmong all the array that follows the above condition print the one having the maximum sum of its elements or print -1 if no
7 min read