Blage's Coding Blage's Coding
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
  • 数组

  • 链表

  • 字符串

  • 二叉树

  • 动态规划

    • 5.最长回文子串
    • 72.编辑距离
    • 300.最长递增子序列
    • 1143.最长公共子序列
    • 239.滑动窗口最大值
    • 64.最小路径和
    • 718.最长重复子数组
    • 221.最大正方形
    • 198.打家劫舍
    • 152.乘积最大子数组
    • 1079.活字印刷
    • 139. 单词拆分
    • 6394. 字符串中的额外字符
    • 10. 正则表达式匹配
    • 1130. 叶值的最小代价生成树
    • 96. 不同的二叉搜索树
    • 279. 完全平方数
    • 416. 分割等和子集
    • 309. 最佳买卖股票时机含冷冻期
    • 312. 戳气球
    • 53. 最大子数组和
    • 1262. 可被三整除的最大和
    • 1186. 删除一次得到子数组最大和
      • 1.动态规划
    • 6912. 构造最长非递减子数组
    • 1911. 最大子序列交替和
    • 834. 树中距离之和
    • 343. 整数拆分
    • 123. 买卖股票的最佳时机 III
    • 115. 不同的子序列
    • 516. 最长回文子序列
    • 132. 分割回文串 II
    • 673. 最长递增子序列的个数
    • 2930. 重新排列后包含指定子字符串的字符串数目
    • 2646. 最小化旅行的价格总和
    • 剑指offer42
    • 剑指offer60
    • 剑指 Offer 49. 丑数
    • 背包问题

  • 深搜回溯

  • 数学贪心

  • 堆栈队列

  • 前缀和

  • 算法设计

  • 位运算

  • WA

  • 算法
  • 动态规划
phan
2023-06-27
目录

1186. 删除一次得到子数组最大和

# 1186. 删除一次得到子数组最大和 (opens new window)

# 1.动态规划

定义dp[ i ][ k ]:表示以元素arr[i]结尾的子数组最大和,其中k代表两种状态,子数组选择删除或者不删除一个元素得到的最大和。

  • dp[ i ][ 0 ]:当前最大和不删除元素,如果前一个dp[ i-1 ][ 0 ]的结果已经小于零,那么arr[i]没有必要与前面的子数组进行合并;如果大于零则可以进行合并。
  • dp[ i ][ 1 ]:当前最大和需要删除一个元素,具体删除哪个元素需要分为两种情况:
    • 如果当前选择删除arr[i],那么最大值为dp[ i ][ 1 ]=dp[ i-1 ][ 0 ]
    • 如果删除的是前面【0,i-1】之间的某个数,那么实际上并不需要我们再遍历一次进行求解,因为去掉的最小值实际上就是dp[i-1][1]中删掉的最小值,这样才能使dp[i-1][1]子数组和是最大的。因此最后最大值为dp[ i ][ 1 ]=dp[ i-1 ][ 1 ]+arr[i]

这里思考,为什么动规可以找到最大的元素?问题简化成如果都不考虑删除的条件下的子数组最大和。也就是说arr[i]和前面子数组合并时,有没有可能只合并子数组的右半部分?答案是不可能的,根据dp数组定义,前面计算得到的子数组和dp[i-1]无论从中间哪个位置劈开,左半部分一定都是大于0。因为如果小于零,则dp[i-1]显然可以只保留右半部分的结果更新最大子数组和。

子数组的“连续性”保证了最大和的连续性,从而保证了合并后arr[i]能够增加的子数组和,区间是最大的。在删除操作中,最然没有任何地方求最小值,但利用dp数组定义反过来推导出dp[ i-1 ][ 1 ]删除的就是最小值。

class Solution {
    public int maximumSum(int[] arr) {
        int[][] dp=new int[arr.length][2];
        dp[0][0]=arr[0];
        dp[0][1]=0;
        int res=arr[0];
        for(int i=1;i<arr.length;i++){
            //不删
            dp[i][0]=Math.max(arr[i],dp[i-1][0]+arr[i]);
            //删除时,要么还是删除前面的元素,要么删除当前元素
            dp[i][1]=Math.max(dp[i-1][1]+arr[i],dp[i-1][0]);
            res=Math.max(res,dp[i][0]);
            res=Math.max(res,dp[i][1]);
        }
        return res; 
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
编辑 (opens new window)
#Leetcode#动态规划
上次更新: 2023/12/15, 15:49:57
1262. 可被三整除的最大和
6912. 构造最长非递减子数组

← 1262. 可被三整除的最大和 6912. 构造最长非递减子数组→

Theme by Vdoing | Copyright © 2023-2024 blageCoder
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式