LeetCode 813. 最大平均值和的分组(C#实现)——动态规划

一、问题

https://leetcode-cn.com/problems/largest-sum-of-averages/solution/

我们将给定的数组 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, 但不是最大值.

说明:

    1 <= A.length <= 100.
    1 <= A[i] <= 10000.
    1 <= K <= A.length.
    答案误差在 10^-6 内被视为是正确的。

二、GitHub实现:https://github.com/JonathanZxxxx/LeetCode/blob/master/Class813.cs

  Blog:https://www.cnblogs.com/zxxxx/

三、思路:动态规划

     1、dp[i,k]视为将数组前i个元素分为k个子数组得到的最大的分数,dp[i,k]的值通过dp[j,k-1]得来,状态转移方程dp[i,k]=max(dp[i,k],dp[j,k-1]+(sum[j]-sum[i])/(j-i)),其中1<=j<i,sum[i]为数组前i个元素的总和

     2、涉及到三个维度的变化,数组长度从1到最大,k的长度从1到最大K,子数组的长度j从1到当前数组长度i-1

四、代码

        public double LargestSumOfAverages(int[] A, int K)
        {
            var sum = new int[A.Length + 1];
            for (int i = 0; i < A.Length; i++)
            {
                sum[i + 1] = sum[i] + A[i];
            }
            var dp = new double[A.Length + 1, K + 1];
            for (int i = 1; i <= A.Length; i++)
            {
                dp[i, 1] = (double)sum[i] / i;
                for (int k = 2; k <= K && k <= i; k++)
                {
                    for (int j = 1; j < i; j++)
                    {
                        dp[i, k] = Math.Max(dp[i, k], dp[j, k - 1] + (double)(sum[i] - sum[j]) / (i - j));
                    }
                }
            }
            return dp[A.Length, K];
        }

 

posted @ 2019-11-01 16:06  落花流水Zxxxx  阅读(205)  评论(0编辑  收藏