You are given an integer array nums and an integer k. You can partition the array into at mostk non-empty adjacent subarrays. The score of a partition is the sum of the averages of each subarray.
Note that the partition must use every integer in nums, and that the score is not necessarily an integer.
Return the maximum score you can achieve of all the possible partitions. Answers within 10-6 of the actual answer will be accepted.
Input:
nums = [9,1,2,3,9], k = 3
Output:
20.00000
Explanation:
The best choice is to partition nums into [9], [1, 2, 3], [9]. The answer is 9 + (1 + 2 + 3) / 3 + 9 = 20.
We could have also partitioned nums into [9, 1], [2], [3, 9], for example.
That partition would lead to a score of 5 + 2 + 6 = 13, which is worse.
Example 2:
1
2
3
4
Input:
nums = [1,2,3,4,5,6,7], k = 4
Output:
20.50000
To maximize the sum of averages when partitioning the array into at most k groups, we want to split the array so that each group has a high average. This means larger numbers should ideally be in their own group, while smaller numbers can be grouped together. Dynamic programming helps us efficiently explore all possible ways to split the array and keep track of the best result for each subproblem.
We use a recursive DFS to partition the array into at most k groups, maximizing the sum of averages. For each partition, we try all possible splits and use memoization to cache results for subproblems. The function search(n, k) returns the largest sum of averages for the first n elements split into k groups.
classSolution {
publicdoublelargestSumOfAverages(int[] nums, int k) {
int n = nums.length;
double[][] dp =newdouble[n + 1][k + 1];
double[] prefix =newdouble[n + 1];
for (int i = 0; i < n; ++i)
prefix[i + 1]= prefix[i]+ nums[i];
for (int i = 1; i <= n; ++i)
dp[i][1]= prefix[i]/ i;
for (int g = 2; g <= k; ++g) {
for (int i = g; i <= n; ++i) {
for (int j = g - 1; j < i; ++j) {
dp[i][g]= Math.max(dp[i][g], dp[j][g - 1]+ (prefix[i]- prefix[j]) / (i - j));
}
}
}
return dp[n][k];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution {
funlargestSumOfAverages(nums: IntArray, k: Int): Double {
val n = nums.size
val dp = Array(n + 1) { DoubleArray(k + 1) }
val prefix = DoubleArray(n + 1)
for (i in nums.indices) prefix[i + 1] = prefix[i] + nums[i]
for (i in1..n) dp[i][1] = prefix[i] / i
for (g in2..k) {
for (i in g..n) {
for (j in (g - 1) until i) {
dp[i][g] = maxOf(dp[i][g], dp[j][g - 1] + (prefix[i] - prefix[j]) / (i - j))
}
}
}
return dp[n][k]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
classSolution:
deflargestSumOfAverages(self, nums: List[int], k: int) -> float:
n = len(nums)
prefix = [0] * (n +1)
for i in range(n):
prefix[i +1] = prefix[i] + nums[i]
dp = [[0.0] * (k +1) for _ in range(n +1)]
for i in range(1, n +1):
dp[i][1] = prefix[i] / i
for g in range(2, k +1):
for i in range(g, n +1):
for j in range(g -1, i):
dp[i][g] = max(dp[i][g], dp[j][g -1] + (prefix[i] - prefix[j]) / (i - j))
return dp[n][k]
impl Solution {
pubfnlargest_sum_of_averages(nums: Vec<i32>, k: i32) -> f64 {
let n = nums.len();
letmut prefix =vec![0.0; n +1];
for i in0..n {
prefix[i +1] = prefix[i] + nums[i] asf64;
}
let k = k asusize;
letmut dp =vec![vec![0.0; k +1]; n +1];
for i in1..=n {
dp[i][1] = prefix[i] / i asf64;
}
for g in2..=k {
for i in g..=n {
for j in (g -1)..i {
dp[i][g] = dp[i][g].max(dp[j][g -1] + (prefix[i] - prefix[j]) / (i - j) asf64);
}
}
}
dp[n][k]
}
}