题目简介:
给定数组 nums
和一个整数 k
。我们将给定的数组 nums
分成 最多 k
个相邻的非空子数组 。 分数 由每个子数组内的平均值的总和构成。
注意我们必须使用 nums
数组中的每一个数进行分组,并且分数不一定需要是整数。
返回我们所能得到的最大 分数 是多少。答案误差在 10-6
内被视为是正确的。
示例 1:
1 2 3 4 5 6
| 输入: nums = [9,1,2,3,9], k = 3 输出: 20.00000 解释: nums 的最优分组是[9], [1, 2, 3], [9]. 得到的分数是 9 + (1 + 2 + 3) / 3 + 9 = 20. 我们也可以把 nums 分成[9, 1], [2], [3, 9]. 这样的分组得到的分数为 5 + 2 + 6 = 13, 但不是最大值.
|
提示:
1 <= nums.length <= 100
1 <= nums[i] <= 10^4
1 <= k <= nums.length
思路:
首先我们将每个元素的前缀和求出来。
定义一个函数solve(n, k)
,用于计算以下标n
开始,分成k
组的最大平均值总和。
- 当
n == dp.size()
时,说明已到数组末尾,返回0
。
- 当
k == 1
时,说明只剩下最后一组,将剩余的元素全部加入这一组即可
- 否则,从
[n, ..., nums.size() - 1]
开始遍历可能的情况,获得最大值。
为防止重复运算,加入res
数组用于存储已经计算过的结果。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| class Solution { public:
double solve(int n, int k, vector<int>& dp, vector<vector<double>>& res){
if(n == dp.size()) return 0;
if(res[n][k]) return res[n][k]; if(k == 1) return (dp[dp.size() - 1] - dp[n]) * 1.0 / (dp.size() - n - 1);
double ans = 0.0; for(int i = n + 1; i < dp.size(); i++){
double temp = (dp[i] - dp[n]) * 1.0 / (i - n) + solve(i, k - 1, dp, res);
ans = max(ans, temp); }
res[n][k] = ans; return ans; }
double largestSumOfAverages(vector<int>& nums, int k) {
vector<int> dp(nums.size() + 1); dp[0] = 0;
for(int i = 0; i < nums.size(); i++) dp[i + 1] = dp[i] + nums[i];
vector<vector<double>> res(dp.size(), vector<double>(k + 1)); return solve(0, k, dp, res); } };
|