欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

最大平均值和的分组

程序员文章站 2022-03-24 17:51:48
...

一、题目描述

题目链接:https://leetcode-cn.com/problems/largest-sum-of-averages/

最大平均值和的分组

 

二、题目分析

题解参考:https://leetcode-cn.com/problems/largest-sum-of-averages/solution/java-di-gui-jie-fa-by-don-vito-corleone-12/

本题使用动态规划的思想解决,首先需要找到状态转移方程。

我们使用一个数组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];
    }