3196. 最大化子数组的总成本
考点
- 划分DP
思路
把数组拆分为若干个连续的子数组,那么以每个点为结尾,向前枚举其区间,然后取最大值,这就是标准的划分DP做法
但是发现一个数学规律:
考虑一段: \[ [a_l, a_{l+1}, a_{l+2}, \dots, a_r] \] 它的 cost 是: \[ a_l - a_{l+1} + a_{l+2} - a_{l+3} + \dots \] 情况一:长度为偶数(例如 4 个数)
比如 [x0, x1, x2, x3]: \[
\text{cost} = x_0 - x_1 + x_2 - x_3
\] 把它分成两段 [x0, x1] 和
[x2, x3],分别算 cost:
[x0, x1]:x0 - x1[x2, x3]:x2 - x3
两段加起来:(x0 - x1) + (x2 - x3) ——
刚好等于原来整段的 cost。
推广一下:对于任意偶数长度 \(2m\): \[ x_0 - x_1 + x_2 - x_3 + \dots + x_{2m-2} - x_{2m-1} \] 可以拆成: \[ (x_0 - x_1) + (x_2 - x_3) + \dots + (x_{2m-2} - x_{2m-1}) \] 也就是说:偶数长度的一段,可以拆成若干个长度为 2 的小段,总代价完全一样。
情况二:长度为奇数(例如 5 个数)
比如 [x0, x1, x2, x3, x4]: \[
\text{cost} = x_0 - x_1 + x_2 - x_3 + x_4
\] 把它拆成三段 [x0,x1], [x2,x3],
[x4]:
[x0,x1]:x0 - x1[x2,x3]:x2 - x3[x4]:x4
加起来:(x0 - x1) + (x2 - x3) + x4 ——
也是刚好等于原来的 cost。
同理,长度为 \(2m+1\) 的一段: \[ x_0 - x_1 + x_2 - x_3 + \dots + x_{2m} \] 可以拆成: \[ (x_0 - x_1) + (x_2 - x_3) + \dots + (x_{2m-2} - x_{2m-1}) + x_{2m} \] 也就是说:奇数长度的一段,可以拆成若干个长度为 2 的段,外加最后一个长度为 1 的段,总代价完全一样。
也就是说,我们只需要管最后两个数字就好了,即
1 | f[i]=max(f[i−1]+a[i−1], f[i−2]+a[i−2]−a[i−1]) |
可以得到如下DP:
1 | class Solution { |
当然,由于只用到了前面两个数字,用不到数组,所以直接用变量替代:
1 | class Solution { |