力扣1186.删除一次得到子数组最大和随笔

"独学而无友,则孤陋而寡闻。"——《礼记·学记》

题目

给你一个整数数组,返回它的某个 非空 子数组(连续元素)在执行一次可选的删除操作后,所能得到的最大元素总和。换句话说,你可以从原数组中选出一个子数组,并可以决定要不要从中删除一个元素(只能删一次哦),(删除后)子数组中至少应当有一个元素,然后该子数组(剩下)的元素总和是所有子数组之中最大的。

注意,删除一个元素后,子数组 不能为空

难度:中等

分析

        动态规划的经典题,晕了😵没做出来,参考了题解,受教了。用dp[i][0]表示取到下标i处值并且未删除得到的最大值,dp[i][1]表示取到下标i处值并且已删除(可以删除下标i)得到的最大值。则对于dp[i][0],必然要求前面的数组也未删除,如果dp[i-1][0]大于0,则可以取前面的数组,否则从下标i开始;对于dp[i][1],可以是前面的数组已经删除过,或者前面的数组未删除,删除下标i的值,取两种情况的最大值。得到状态转移方程:

dp[i][0]=max(dp[i-1][0],0)+arr[i]

dp[i][1]=max(dp[i-1][1]+arr[i],dp[i-1][0])

        由于当前状态的值只与前一状态的值有关,故使用两个变量存储dp即可。

解答

class Solution {
public:
    int maximumSum(vector<int>& arr) {
        int n=arr.size(),ans=arr[0];
        //dp0表示包括当前值未删除的最大值,dp1表示包括当前值已删除的最大值
        int dp0=arr[0],dp1=0;
        for (int i=1;i<n;i++){
            //未删除:包含前面的值或从当前值开始
            int dp0_new=max(dp0,0)+arr[i];
            //已删除:前面已删除则加上当前值,否则删除当前值
            int dp1_new=max(dp0,dp1+arr[i]);
            dp0=dp0_new;
            dp1=dp1_new;
            ans=max(ans,max(dp0,dp1));
        }
        return ans;
    }
};

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值