最大平均值和的分组
我们将给定的数组 A 分成 K 个相邻的非空子数组 ,我们的分数由每个子数组内的平均值的总和构成。计算我们所能得到的最大分数是多少。
注意我们必须使用 A 数组中的每一个数进行分组,并且分数不一定需要是整数。
示例:
输入:
A = [9,1,2,3,9]
K = 3
输出: 20
解释:
A 的最优分组是[9], [1, 2, 3], [9]. 得到的分数是 9 + (1 + 2 + 3) / 3 + 9 = 20.
我们也可以把 A 分成[9, 1], [2], [3, 9].
这样的分组得到的分数为 5 + 2 + 6 = 13, 但不是最大值.
思路:
首先 要明确就是把组划分的越多,则平均数之和越大(比如把每一个分成单独的一个,加和就是这个数的全部加和了),所以要分成最大,那就一定是分成k组,
所以,我们定义dp[i][k]表示将A[0]到A[i]这i+1个元素划分成为k组的话,平均数之和的最大值,然后推导递推公式:
1)如果k == 1,说明我们将这i+1个元素归为1组,所以dp[i][k] = avg(A[0],...A[i]);
2)如果k > 1,那么我么可以采用的策略是:将A[j], A[i]这i-j+1个数划分为1组,那么此时就需要将A[0],...A[j - 1]划分成为另外的k-1组(k - 1 <= j <= i)。在这所有的划分方法中,我们需要取使得dp[i][k]达到最大值的那种划分,所以dp[i][k] = max(dp[j - 1][k - 1] + avg(A[j],...A[i])), k - 1 <= j <= i。最后得到的dp[n - 1][K]即为所求。
由于我们需要求不同区间的平均数,所以在程序的第一步,我们首先利用O(n)的时间复杂度计算出A数组的累积和,这样在后面就可以在O(1)时间内求出任意区间内数值的平均值了。
算法的时间复杂度是O(kn^2),空间复杂度是O(kn),但是注意到dp[i][k]之和dp[j][k - 1]有关,其中k - 1 <= j <= i。所以实际上我们还可以进一步优化,只需要两行就可以了,我这里先不写到优化
另外,在写sum的时候也要优化一下才行呀
class test3 {
public static void main(String[] args) {
// String arr[] = {"10","0001", " 111001", "1","0"};
int m = 5;
int n =3;
int k = 3;
int arr[] = {9,1,2,3,9};
Solution s = new Solution();
double x = s.largestSumOfAverages(arr,k);
System.out.println(x);
}
static class Solution {
public double largestSumOfAverages(int[] A, int K) {
int len = A.length;
double sum[] = new double[len];
sum[0] = A[0];
for(int i = 1;ii+1){
// continue;
// }a
else { //i指的是到i为止,j要小鱼i,从j到i化成一组,然后从0到j-1化成前k-1组的
for(int j =1;j<=i;j++){//j为啥不从1开始
double part1 = dp[j-1][k-1];
double part2 =(sum[i] - sum[j - 1])/(i-j);
if(dp[i][k]
额mmm
这个真的郁闷了,感觉思路没问题,但是一直或输出是Infinity,,不清楚为啥
参考:https://blog.csdn.net/magicbean2/article/details/79893634