"独学而无友,则孤陋而寡闻。"——《礼记·学记》
题目
给你一个整数数组,返回它的某个 非空 子数组(连续元素)在执行一次可选的删除操作后,所能得到的最大元素总和。换句话说,你可以从原数组中选出一个子数组,并可以决定要不要从中删除一个元素(只能删一次哦),(删除后)子数组中至少应当有一个元素,然后该子数组(剩下)的元素总和是所有子数组之中最大的。
注意,删除一个元素后,子数组 不能为空。
难度:中等
分析
动态规划的经典题,晕了😵没做出来,参考了题解,受教了。用dp[i][0]表示取到下标i处值并且未删除得到的最大值,dp[i][1]表示取到下标i处值并且已删除(可以删除下标i)得到的最大值。则对于dp[i][0],必然要求前面的数组也未删除,如果dp[i-1][0]大于0,则可以取前面的数组,否则从下标i开始;对于dp[i][1],可以是前面的数组已经删除过,或者前面的数组未删除,删除下标i的值,取两种情况的最大值。得到状态转移方程:
由于当前状态的值只与前一状态的值有关,故使用两个变量存储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;
}
};