Maximum average sum partition of an array in C++


Problem statement

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?

Example

If input array is {9, 2, 5, 3, 10} then we can partition array as follows −

{9} {2, 5, 3} and {10} then average sum of this is −

9 + (2 + 5 + 3)/ 3 + 10 = 22.33

Algorithm

We can use memorization technique to solve this problem −

  • Let memo[i][k] be the best score portioning A[i to n-1] into at most K partss
  • In the first group, we partition A[i to n-1] into A[i to j-1] and A[j to 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))

Example

Let us now see an example −

#include <bits/stdc++.h>
using namespace std;
define MAX 1000
double memo[MAX][MAX];
double score(int n, vector<int>& arr, int k) {
   if (memo[n][k] > 0) {
      return memo[n][k];
   }
   double sum = 0;
   for (int i = n - 1; i > 0; i--) {
      sum += arr[i];
      memo[n][k] = max(memo[n][k], score(i, arr, k - 1) + sum / (n - i));
   }
   return memo[n][k];
}
double getLargestSum(vector<int>& arr, int K) {
   int n = arr.size();
   double sum = 0;
   memset(memo, 0.0, sizeof(memo));
   for (int i = 0; i < n; i++) {
      sum += arr[i];
      memo[i + 1][1] = sum / (i + 1);
   }
   return score(n, arr, K);
}
int main() {
   vector<int> arr = {9, 2, 5, 3, 10}; int K = 3;
   cout << "Largest sum = " << getLargestSum(arr, K) << endl;
   return 0;
}

Output

When you compile and execute above program. It generates following output -

Largest sum = 22.3333

Updated on: 31-Dec-2019

121 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements