分隔数组以得到最大和

题目描述:

给出整数数组 A,将该数组分隔为长度最多为 K 的几个(连续)子数组。分隔完成后,每个子数组的中的值都会变为该子数组中的最大值。
返回给定数组完成分隔后的最大和。

示例:1
输入:A = [1,15,7,9,2,5,10], K = 3
输出:84
解释:A 变为 [15,15,15,9,10,10,10]
提示:
1 <= K <= A.length <= 500
0 <= A[i] <= 10^6
因为 k=3 可以分隔成 [1,15,7] [9] [2,5,10],结果为 [15,15,15,9,10,10,10],和为 84,是该数组所有分隔变换后元素总和最大的。
若是分隔成 [1] [15,7,9] [2,5,10],结果就是 [1, 15, 15, 15, 10, 10, 10] 但这种分隔方式的元素总和(76)小于上一种。

示例 2:
输入:arr = [1,4,1,5,7,3,6,1,9,9,3], k = 4
输出:83

示例 3:
输入:arr = [1], k = 1
输出:1

思路

动态规划

dp[i]:数组的前 i 个数即 nums[【0,1…i-1】,被切了 Y−1 刀,分割成 Y 个数组,满足每个数组的个数最大值不超过 K,每个数组的值变成最大值,分割后的最大和,如上图,当被分成Y=3 个部分时,第一部分的最大值为 15,第二部分为 9,第三部分 10,每一部分的每个值都上升为当前部分的局部 max,红色字体为新的值,累加后,求其最大值
在这里插入图片描述

求 dp[i-1],
表示数组的前 i 个数即 nums[0,1...i-2],第二部分是 nums[i-1],也就是说 dp[i-1] + max(nums[i-1])*(i-(i-1))
求 dp[i-2],
表示数组的前 i-1 个数即 nums[0,1...i-3],第二部分是 nums[i-2...i-1],也就是说 dp[i-2] + max(nums[i-2...i-1]) * (i-(i-2))
求 dp[i-3],
表示数组的前 i-2 个数即 nums[0,1...i-4],第二部分是 nums[i-3...i-1],也就是说 dp[i-3]+ max(nums[i-3...i-1]) * (i-(i-3))
...
求 dp[0],
表示数组的前 1 个数即 nums[0,0],第二部分是nums[0...i−1],也就是说 dp[0] + max(nums[0...i-1])* (i-(0))

推导出 dp[i]=max(dp[i],dp[j]+(i-j)*MAX),
其中 MAX 是 nums[j...i−1] 范围内的局部最大值,一旦找到最大值,该范围内的所有值都改成这个局部最大值 MAX,
其中 0 =< j< i

代码

    public int maxSumAfterPartitioning(int[] A, int K) {
        int n = A.length;
        int[] dp = new int[n + 1];
        //核心思想是每到一个数,就把这个数放到一个新的框子里,然后开始往前调整
        //框子里的值为进来的数的最大值
        //往前取,最多只能取到i-k+1,每取一个数,放进框子里,看放这个数的结果更大还是不放大
        for (int i = 0; i <= n; i++) {
            int j = i - 1;
            int max = dp[i];
            while ((i - j) <= K && j >= 0) {
                max = Math.max(max, A[j]);
                dp[i] = Math.max(dp[i], dp[j] + (i - j) * max);
                j--;
            }
        }
        return dp[n];
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haikuotiankongdong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值