3196. 最大化子数组的总成本
https://leetcode.cn/problems/maximize-total-cost-of-alternating-subarrays/description/
给你一个长度为\(n\)的整数数组\(nums\)。
子数组\(nums[l..r]\)(其中\(0 <= l <= r < n\))的 成本 定义为:
\(cost(l, r) = nums[l] - nums[l + 1] + ... + nums[r] * (−1)^{r−l}\)
你的任务是将\(nums\)分割成若干子数组,使得所有子数组的成本之和 最大化,并确保每个元素 正好 属于一个子数组。
具体来说,如果\(nums\)被分割成\(k\)个子数组,且分割点为索引\(i_1, i_2, ..., i_{k − 1}\)(其中 \(0 <= i_1 < i_2 < ... < i_{k-1} < n - 1\)),则总成本为:
\(cost(0, i_1) + cost(i_1 + 1, i_2) + ... + cost(i_{k − 1} + 1, i_{n − 1})\)
返回在最优分割方式下的子数组成本之和的最大值。
注意:如果\(nums\)没有被分割,即\(k = 1\),则总成本即为\(cost(0, n - 1)\)。
示例 1:
输入: nums = [1,-2,3,4]
输出: 10
解释:
一种总成本最大化的方法是将 [1, -2, 3, 4] 分割成子数组 [1, -2, 3] 和 [4]。总成本为 (1 + 2 + 3) + 4 = 10。
示例 2:
输入: nums = [1,-1,1,-1]
输出: 4
解释:
一种总成本最大化的方法是将 [1, -1, 1, -1] 分割成子数组 [1, -1] 和 [1, -1]。总成本为 (1 + 1) + (1 + 1) = 4。
示例 3:
输入: nums = [0]
输出: 0
解释:
无法进一步分割数组,因此答案为 0。
示例 4:
输入: nums = [1,-1]
输出: 2
解释:
选择整个数组,总成本为 1 + 1 = 2,这是可能的最大成本。
提示:
\(1 <= nums.length <= 10^5\)
\(-10^9 <= nums[i] <= 10^9\)
方法二:
转化一下题意:给\(nums\)的每个元素前面加上正负号,其中正号可以任意添加(因为可以视为一个子数组的开头),负号元素只能紧接在正号元素后面。求最大和。
题意转化之后,做法就很显然了。维护 \(f(i,j=0/1)\) 表示第 iii 个元素是正\((j=0)\)或负\((j=1)\)号元素的最大前缀和,转移方程为
,答案就是\(\max(f(n, 0), f(n, 1))\)。复杂度 \(\mathcal{O}(n)\)。
class Solution {
public:
long long maximumTotalCost(vector<int>& nums) {
int n=nums.size();
long long INF=1e18;
long long f[n][2];
for(int i=0;i<n;i++){
f[i][0]=f[i][1]=-INF;
}
f[0][0]=nums[0];//这个是+
for(int i=1;i<n;i++){
f[i][0]=max(f[i-1][0],f[i-1][1])+nums[i];//加
f[i][1]=f[i-1][0]-nums[i];//-
}
return max(f[n-1][0],f[n-1][1]);
}
};
方法二:
我们从后往前遍历数组的元素,从终点向起点归并,得出最大总成本。
规定f[i][1]表示当前数i变号,f[i][0]表示当前数i不变号。
如果前一个数变号,那么当前数的一定不变号;
如果前一个数不变号,那么当前的数可能变号也可能不变号;
于是当前的数变号的话,f[i][1]=f[i+1][0]-nums[i];
不变号的话f[i][0]为f[i+1][1]+nums[i]和f[i+1][0]+nums[i]中的较大者
第一个数一定是不变号的,所以结果为f[0][0];
class Solution {
public:
long long maximumTotalCost(vector<int>& nums) {
int n=nums.size();
vector<array<long long,2>>f(n+1);
for(int i=n-1;i>=0;i--){
f[i][1]=f[i+1][0]-nums[i];
f[i][0]=max(f[i+1][1]+nums[i],f[i+1][0]+nums[i]);
}
return f[0][0];
}
};