一、题目描述
题目链接:https://leetcode-cn.com/problems/largest-sum-of-averages/
二、题目分析
本题使用动态规划的思想解决,首先需要找到状态转移方程。
我们使用一个数组dp[i][k]来表示在前i个数的情况下,分成k组的最大平均值。对于每一个dp[i][k],我们可以把后面的几个数看成一组,前面几个数构成k-1个组,通过这个策略列举所有的可能,从中找到最大值,即:
dp[i][k] = dp[j][k-1] + mean(j+1,i) 【j<i】
其中 j 为小于 i 的数字,标示将 j+1到 i 的数看成一组,由此求一个均值,再加上前面的最大值。因为我们是从前往后的dp,所以前面的值是知道的。
非递归的方法实在是理解不了,还是看看递归的吧。
三、代码
private double[][] dp;
private int[] A;
public double largestSumOfAverages(int[] A, int K) {
int len = A.length;
dp = new double[len+1][K+1];
this.A = A;
double sum = 0.0;
// 初始化dp,只有一个分组的情况。
for (int i = 0; i < len; ++i) {
sum += A[i];
dp[i+1][1] = sum/(i+1);
}
helper(len,K);
return dp[len][K];
}
private double helper(int n, int k) {
if (dp[n][k] != 0) return dp[n][k];
// 如果不够分这么多组
if (n < k) return 0;
double sum = 0.0;
for (int i = n-1; i > 0; --i) {
// 这里是i-1+1,i-1为真实数组下标,+1指后面的数
sum += A[i];
dp[n][k] = Math.max(dp[n][k],sum / (n-i) + helper(i,k-1));
}
return dp[n][k];
}