LeetCode 813 最大平均值和的分组[动态规划 前缀和] HERODING的LeetCode之路
Posted HERODING23
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 813 最大平均值和的分组[动态规划 前缀和] HERODING的LeetCode之路相关的知识,希望对你有一定的参考价值。
解题思路:
一道非常有有参考价值的动态规划题型,是前缀和和动态规划的结合,首先计算前缀和,便于求解dp时计算区间的和,对于dp数组,dp[i][j]表示对于长度为i的序列,将其分为j组所得到的最大平均值,那么就可以开始遍历了,首先遍历整个序列,i为当前遍历的序列的长度,对于当前的长为i的序列,遍历K,即将序列分为1——K组,对于每个分组,状态转移方程为:dp[i][k] = max(dp[i][k], dp[j][k - 1] + t)
,t表示序列中j——i子序列的平均值,代码如下:
class Solution
public:
double largestSumOfAverages(vector<int>& nums, int K)
int n = nums.size();
vector<vector<double>> dp(n + 1, vector<double>(K + 1));
vector<double> prefix(n + 1);
for(int i = 1; i <= n; i ++)
prefix[i] = prefix[i - 1] + nums[i - 1];
// 遍历序列
for(int i = 1; i <= n; i ++)
dp[i][1] = prefix[i] / i;
for(int k = 2; k <= K; k ++)
for(int i = k; i <= n; i ++)
// 分割区间
for(int j = 1; j < i; j ++)
double t = (prefix[i] - prefix[j]) / (i - j);
dp[i][k] = max(dp[i][k], dp[j][k - 1] + t);
return dp[n][K];
;
观察发现由于dp[i][k]只用到k-1的数据,因此可以优化dp数组为一维数组,注意序列长度要从大到小遍历,代码如下:
class Solution
public:
double largestSumOfAverages(vector<int>& nums, int K)
int n = nums.size();
vector<double> dp(n + 1);
vector<double> prefix(n + 1);
for(int i = 1; i <= n; i ++)
prefix[i] = prefix[i - 1] + nums[i - 1];
// 遍历序列
for(int i = 1; i <= n; i ++)
dp[i] = prefix[i] / i;
for(int k = 2; k <= K; k ++)
for(int i = n; i >= k; i --)
// 分割区间
for(int j = 1; j < i; j ++)
double t = (prefix[i] - prefix[j]) / (i - j);
dp[i] = max(dp[i], dp[j] + t);
return dp[n];
;
以上是关于LeetCode 813 最大平均值和的分组[动态规划 前缀和] HERODING的LeetCode之路的主要内容,如果未能解决你的问题,请参考以下文章