思路:
一个简单的数学结论:
划分份数越多,平均值之和越大,因此想要取得最大值必然是恰好划分成 k 份
- 用 表示 前i个元素划分成j份的最大平均和,则答案就是
- 当 时, 就是 元素的平均值
- 当 时,我们可以把区间 划分成 和 两部分, 等于所有这些合法的切分方式的平均值和的最大值
- 所以状态转移方程就是
dp[i][j]=max(dp[i][j],dp[x][j-1]+(s[i]-s[x])/(i-x));
其中 dp[x][j - 1] + (s[i] - s[x]) / (i - x) 表示为 x 位置 之前的最大值分组和 + 当前位置平均值
class Solution {
public:
double largestSumOfAverages(vector<int>& nums, int k)
{
int n = nums.size();
vector<double> s(n+1);
for(int i=0;i<n;i++) s[i+1]=s[i]+nums[i];
vector<vector<double>> dp(n+1,vector<double>(k+1));
for(int i=1;i<=n;i++) dp[i][1]=s[i]/i;
for(int j=2;j<=k;j++) //枚举分组数
for(int i=j;i<=n;i++) //枚举分组元素
for(int x=j-1;x<i;x++) //枚举分割位置
dp[i][j]=max(dp[i][j],dp[x][j-1]+(s[i]-s[x])/(i-x));
return dp[n][k];
}
};