给定一个数组,我们将一行数字 A 划分为至多 K 个相邻(非空)组,那么分数是每个组的平均值之和。最高可以打多少分?
例子:
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.
一个简单的解决方案是使用递归。一个有效的解决方案是记忆,我们将最大的分数保持在 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],那么我们的候选划分的分数为 average(i, j) + score(j, k-1)),其中 average(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))
对于所有 i 从 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
Javascript
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 之前结束,那么我们的候选划分的分数为 average(i, j) + dp(j, k-1))。一般情况下的递归是 dp(i, k) = max(average(i, N), (average(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
蟒蛇3
# 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
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。