今日刷题 动态dp比较简单状态机模型

题目描述:1186. 删除一次得到子数组最大和

一个很好的题解,受益匪浅

比较通俗易懂的dp - 删除一次得到子数组最大和 - 力扣(LeetCode):

我们定义f ( i ) 和 g ( i ),其中 f( i ) 表示不删除元素的情况下最大子数组和(以arr[i]结尾),g( i ) 代表删除元素的情况下的最大子数组和(以arr[i]结尾)。

f(i) = Math.max(f(i-1)+arr[i],arr[i]) //要么是当前元素累加之前的和,要么是重新从当前元素开始
g(i) = Math.max(g(i-1)+arr[i],f(i-1)) //要么是加上当前元素,也就是维持之前删除某个元素的情形,即g[i-1]+arr[i]//要么是删除当前这个元素,那么区间[0, i-1]就是不删除元素的情况,即f(i-1)+0(注意是f不是g!!)

问题在于初始化:

f(0)= arr[0] //因为必须要有元素,不能为 0 个元素

g(0) = 什么呢?

举个例子,假设我们要计算g(1):

g(1) = Math.max(g(0)+arr[1],f(0))//题目提到至少保留一个元素,所以不可能是之前删过元素(g(0)+arr[1]),必须要选f(0),即g(0)要足够小
// g(0) + arr[1] < arr[0]
// g(0) < arr[0] - arr[1]
// 因为 - 10^4 <= arr[i] <= 10^4,所以arr[0]-arr[1] >= -2 * 10^4,即g(0)取-20001即可

完整AC代码

class Solution {
    public int maximumSum(int[] arr) {
        int len=arr.length;
        int[] f=new int[len];
        int[] g=new int[len];
        int res=arr[0];
        f[0]=arr[0];
        g[0]=-20001;
        for(int i=1;i

你可能感兴趣的:(Leetcode刷题,算法,leetcode,数据结构)