【每日一题Day182】LC1043分隔数组以得到最大和 | dp

简介: 【每日一题Day182】LC1043分隔数组以得到最大和 | dp

分隔数组以得到最大和【LC1043】

给你一个整数数组 arr,请你将该数组分隔为长度 最多 为 k 的一些(连续)子数组。分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值。

返回将数组分隔变换后能够得到的元素最大和。本题所用到的测试用例会确保答案是一个 32 位整数。

二十分钟 满足了

  • 思路
    使用动态规划,将前i个元素进行分割的最大和,可以枚举分割点由之前的状态转移得到,因此可以定义状态dp[i+1]为将i个元素分隔变换后能够得到的元素最大和
  • 明确 dp 函数/数组的定义

定义状态dp[i+1]为将i个元素分隔变换后能够得到的元素最大和

  • 确定 base case,初始状态的值:dp[0]=0
  • 确定「状态」,也就是原问题和子问题中会变化的变量

    本题中状态为分隔变换后能够得到的元素最大和

  • 确定「选择」,也就是导致「状态」产生变化的行为

    i个元素最长可以分割的子数组为nums[ik+1:i]因此可以枚举与nums[i]为一组的左端点j[ik+1,i]此时的最大和为将nums[0:j1]进行分割的最大值nums[j:i]变换后的值之和

。实现时,使用变量记录当前子数组nums[j:i]中元素的最大值mx,于是可以得到状态转移方程image.png

实现

class Solution {
    public int maxSumAfterPartitioning(int[] arr, int k) {
        int n = arr.length;
        int[] dp = new int[n + 1];       
        for (int i = 0; i < n; i++){
            int mx = arr[i];
            for (int j = i; j >= Math.max(0, i - k + 1); j--){
                mx = Math.max(mx, arr[j]);
                dp[i + 1] = Math.max(dp[i + 1], dp[j] + mx * (i - j + 1));
            }
        }
        return dp[n];
    }
}

复杂度

  • 时间复杂度:O(nk)
  • 空间复杂度:O(n)



目录
相关文章
|
5月前
|
索引
【每日一题Day183】LC1187使数组严格递增 | dp
【每日一题Day183】LC1187使数组严格递增 | dp
41 0
|
5月前
【每日一题Day185】LC1027最长等差数列 | dp
【每日一题Day185】LC1027最长等差数列 | dp
43 0
|
5月前
【每日一题Day289】LC1749任意子数组和的绝对值的最大值 | dp
【每日一题Day289】LC1749任意子数组和的绝对值的最大值 | dp
42 0
|
5月前
【每日一题Day189】LC1048最长字符串链 | dp+排序
【每日一题Day189】LC1048最长字符串链 | dp+排序
45 0
|
5月前
【每日一题Day194】LC970强整数 | 枚举
【每日一题Day194】LC970强整数 | 枚举
36 0
|
5月前
【每日一题Day268】LC415字符串相加 | 模拟
【每日一题Day268】LC415字符串相加 | 模拟
44 0
|
5月前
【每日一题Day161】LC1641统计字典序元音字符串的数目 | 数位dp
【每日一题Day161】LC1641统计字典序元音字符串的数目 | 数位dp
46 0
|
5月前
【每日一题Day225】LC2559统计范围内的元音字符串数 | 前缀和 二分查找
【每日一题Day225】LC2559统计范围内的元音字符串数 | 前缀和 二分查找
48 0
|
5月前
【每日一题Day242】LC1262可被三整除的最大和 | 贪心 dp
【每日一题Day242】LC1262可被三整除的最大和 | 贪心 dp
48 0
|
5月前
【每日一题Day204】LC1330翻转子数组得到最大的数组值 | 数学
【每日一题Day204】LC1330翻转子数组得到最大的数组值 | 数学
41 1