# Maximum average sum partition of an array

• Difficulty Level : Hard
• 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 ``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 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 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 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

 ``

Output

`20`

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

 ``

Output

`20`

Time Complexity: O(n2*K)
Auxiliary Space: O(n)

My Personal Notes arrow_drop_up