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 than 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 .

[sourcecode language=”CPP”]

// 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 partioning size

cout << largestSumOfAverages(A, K) << endl;

return 0;

}

[/sourcecode]

**Output:**

20

Above problem can now be easily understood as dynamic programming.

Let dp(i, k) be the best score partioning 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.

[sourcecode language=”CPP”]

// 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 partioning size

cout << largestSumOfAverages(A, K) << endl;

return 0;

}

[/sourcecode]

**Output:**

20

## Recommended Posts:

- Partition an array such into maximum increasing segments
- Partition into two subarrays of lengths k and (N - k) such that the difference of sums is maximum
- Path with maximum average value
- Find maximum average subarray of k length
- Students with maximum average score of three subjects
- Optimal partition of an array into four parts
- Find a partition point in array
- Equal sum array partition excluding a given element
- Minimum toggles to partition a binary array so that it has first 0s then 1s
- Print equal sum sets of array (Partition problem) | Set 1
- Print equal sum sets of array (Partition Problem) | Set 2
- Average numbers in array
- Program for average of an array (Iterative and Recursive)
- Count occurrences of the average of array elements with a given number
- Average of remaining elements after removing K largest and K smallest elements from array

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.