最大平均值和的分组

一、题目描述

题目链接: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];
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值