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++
#include <bits/stdc++.h>
using namespace std;
#define MAX 1000
double memo[MAX][MAX];
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];
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;
cout << largestSumOfAverages(A, K) << endl;
return 0;
}
|
Java
import java.util.Arrays;
import java.util.Vector;
class GFG
{
static int MAX = 1000 ;
static double [][] memo = new double [MAX][MAX];
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);
memo[i + 1 ][ 1 ] = sum / (i + 1 );
}
return score(n, A, K);
}
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));
}
}
|
Python3
MAX = 1000
memo = [[ 0.0 for i in range ( MAX )]
for i in range ( MAX )]
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]
memo[i + 1 ][ 1 ] = int ( sum / (i + 1 ))
return score(n, A, K)
if __name__ = = '__main__' :
A = [ 9 , 1 , 2 , 3 , 9 ]
K = 3
print (largestSumOfAverages(A, K))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int MAX = 1000;
static double [,] memo = new double [MAX, MAX];
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];
memo[i + 1, 1] = sum / (i + 1);
}
return score(n, A, K);
}
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));
}
}
|
Javascript
<script>
let MAX = 1000;
let memo = new Array(MAX).fill(0).map(() => new Array(MAX).fill(0));
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];
memo[i + 1][1] = sum / (i + 1);
}
return score(n, A, K);
}
let A = [9, 1, 2, 3, 9];
let K = 3;
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++
#include <bits/stdc++.h>
using namespace std;
double largestSumOfAverages(vector< int >& A, int K)
{
int n = A.size();
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];
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];
}
int main()
{
vector< int > A = { 9, 1, 2, 3, 9 };
int K = 3;
cout << largestSumOfAverages(A, K) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static double largestSumOfAverages( int [] A, int K)
{
int n = A.length;
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];
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 ];
}
public static void main(String[] args)
{
int []A = { 9 , 1 , 2 , 3 , 9 };
int K = 3 ;
System.out.println(largestSumOfAverages(A, K));
}
}
|
Python3
def largestSumOfAverages(A, K):
n = len (A);
pre_sum = [ 0 ] * (n + 1 );
pre_sum[ 0 ] = 0 ;
for i in range (n):
pre_sum[i + 1 ] = pre_sum[i] + A[i];
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 ]);
A = [ 9 , 1 , 2 , 3 , 9 ];
K = 3 ;
print (largestSumOfAverages(A, K));
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static double largestSumOfAverages( int [] A,
int K)
{
int n = A.Length;
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];
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];
}
public static void Main(String[] args)
{
int []A = { 9, 1, 2, 3, 9 };
int K = 3;
Console.WriteLine(largestSumOfAverages(A, K));
}
}
|
Javascript
<script>
function largestSumOfAverages(A , K) {
var n = A.length;
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];
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];
}
var A = [ 9, 1, 2, 3, 9 ];
var K = 3;
document.write(largestSumOfAverages(A, K));
</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 : 74 Input : arr[] = {10, 10, 10}, Output : 20 Input arr[] = {10}, Output : -1 [
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