📜  数组的最大平均和分区

📅  最后修改于: 2021-05-06 22:35:59             🧑  作者: Mango

给定一个数组,我们将数字A的行划分为最多K个相邻(非空)组,则分数是每个组的平均值之和。最高得分是多少?

例子:

一个简单的解决方案是使用递归。一个有效的解决方案是记忆,我们将最大分数保持为k,例如,将1,2,3…保持为k;

令memo [i] [k]是将A [i..n-1]分成最多K个部分的最佳分数部分。在第一组中,我们将A [i..n-1]划分为A [i..j-1]和A [j..n-1],然后我们的候选分区的平均得分为(i,j)+分数(j,k-1)),其中平均值(i,j)=(A [i] + A [i + 1] +…+ A [j-1])/(j – i)。我们在这些中得分最高。

总的来说,在一般情况下,我们的递归为:
memo [n] [k] = max(memo [n] [k],score(memo,i,A,k-1)+ average(i,j))
对于所有我,从n-1到1。

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& 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& 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 A = { 9, 1, 2, 3, 9 };
    int K = 3; // atmost partioning 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 partioning 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 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 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 A = new List(arr);
        int K = 3;
        Console.WriteLine(largestSumOfAverages(A, K));
    }
}
  
// This code is contributed by Rajput-Ji


C++
// CPP program for maximum average sum partition
#include 
using namespace std;
  
double largestSumOfAverages(vector& 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 A = { 9, 1, 2, 3, 9 };
    int K = 3; // atmost partioning 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 partioning 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 partioning 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 partioning size
    Console.WriteLine(largestSumOfAverages(A, K));
}
}
  
// This code is contributed by PrinciRaj1992


输出:
20

上面的问题现在可以很容易地理解为动态编程。
令dp(i,k)是将A [i:j]分成最多K个部分的最佳分数。如果第一组我们将A [i:j]划分为j之前的结尾,则我们的候选分区的得分为平均值(i,j)+ dp(j,k-1))。在一般情况下,递归是dp(i,k)= max(平均值(i,N),(平均值(i,j)+ dp(j,k-1)))。我们可以预先计算前缀和,以快速执行输出代码。

C++

// CPP program for maximum average sum partition
#include 
using namespace std;
  
double largestSumOfAverages(vector& 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 A = { 9, 1, 2, 3, 9 };
    int K = 3; // atmost partioning 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 partioning 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 partioning 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 partioning size
    Console.WriteLine(largestSumOfAverages(A, K));
}
}
  
// This code is contributed by PrinciRaj1992
输出:
20