将数组分成相邻的若干组

示例:

 

 1 <= k <= nums.length

因为k最大为数组的长度,所以本题的最大分数一定出现在将数组分成k组。假设分成k-1组,那么肯定有一个子数组中的个数大于1,这个子数组还可以继续划分,划分的越多,平均值和越大。

所以分成k组时所能得到最大的分数。

用动态规划来求解。

首先为了求解平均值之和,先求出前缀和数组,便于后续的求解。

 

假设数组的长度为n,定义vector<vector<double>>dp(n+1,vector<double>(k+1,0))。

dp[i][j]表示将[0,i-1](即前i个元素)分成j段所能得到的最大平均值的和。所以i>=j,因为[0,i-1]当中只有i个元素,最多分成i段,所以j的最大值为i。

首先初始化,当j=1时,就是将[0,i-1]分成一段。

然后就是分成多段的情况,从2开始,k结束。所以第一层循环为遍历分成的段数。

 

然后就是需要分解的数组。 

因为分解的段数为j,最少需要j个元素,所以所需要分解的数组的长度就从j开始。最多到数组结束。

第一层确定了分解的段数,第二层确定了所需分解的数组 。

dp[i][j]表示[0,i-1]分成j段所得到的最大平均值和。i>=j

所以把[0,i-1]分成两部分,第一部分为[0,x-1],第二部分为[x,i-1]。遍历x,看能得到的最大平均值和为多少。第二个部分为一组,平均值和为prsum[i-1+1]-prsum[x])/(i-1-x+1)。第一个部分为j-1组,平均值和为dp[x][j-1]。所以x的取值范围为x>=j-1并且x<=i-1。

 所以完整代码如下:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值