3040. 相同分数的最大操作数目 II
考点
- 区间DP
思路
一、问题重述(抽象化)
给定一个整数数组 \[ \text{nums} = [a_1, a_2, \dots, a_n] \] 每次操作可以 删除数组中相邻或两端的一对元素,具体有三种形式:
删除前两个元素 \[ (a_i, a_{i+1}) \]
删除后两个元素 \[ (a_{j-1}, a_j) \]
删除首尾两个元素 \[ (a_i, a_j) \]
但有一个全局约束:
所有操作中,被删除的一对元素之和 必须相同。
目标是: 在满足该约束的前提下,最大化操作次数。
二、关键观察(问题建模的核心)
1️⃣ 第一次操作决定“全局分数”
设每次操作的分数为: \[ s = x + y \] 由于所有操作分数必须一致,因此:
- 第一次操作的分数 \(s\) 唯一决定了后续所有操作
- 而第一次操作 只有三种可能:
\[ \begin{aligned} s_1 &= a_1 + a_2 \\ s_2 &= a_1 + a_n \\ s_3 &= a_{n-1} + a_n \end{aligned} \]
因此,只需枚举这三个候选分数,分别计算在该分数约束下最多能做多少步,取最大值即可。
三、状态设计(区间建模)
无论使用 区间 DP 还是 记忆化搜索,核心状态均为:
当前剩余子数组为区间 \([i, j]\),在目标分数 \(s\) 下,最多能做多少次操作。
状态定义(数学形式)
固定分数 \(s\)
\[ f(i, j) = \text{区间 } [i, j] \text{ 内,所有操作和为 } s \text{ 的最大操作次数} \]
边界条件: \[ i \ge j \quad \Rightarrow \quad f(i, j) = 0 \] (区间内不足两个元素,无法继续操作)
四、状态转移方程(核心)
在区间 \([i, j]\) 内,若某种删除方式满足和为 \(s\),即可进行一次操作,并转移到更小区间。
1️⃣ 删除首尾
若: \[ a_i + a_j = s \] 则: \[ f(i, j) = \max\left(f(i, j),\ 1 + f(i+1, j-1)\right) \]
2️⃣ 删除前两个
若: \[ a_i + a_{i+1} = s \] 则: \[ f(i, j) = \max\left(f(i, j),\ 1 + f(i+2, j)\right) \]
3️⃣ 删除后两个
若: \[ a_{j-1} + a_j = s \] 则: \[ f(i, j) = \max\left(f(i, j),\ 1 + f(i, j-2)\right) \]
总结(统一转移)
\[ f(i, j) = \max \begin{cases} 1 + f(i+1, j-1), & a_i + a_j = s \\ 1 + f(i+2, j), & a_i + a_{i+1} = s \\ 1 + f(i, j-2), & a_{j-1} + a_j = s \end{cases} \]
五、两种实现方式
实现一:区间 DP(三维,枚举分数)
思路
用三维 DP 数组: \[ f[i][j][k] \]
- \(i, j\):区间端点(1-based)
- \(k \in \{0,1,2\}\):对应三种候选分数
按区间长度从小到大枚举
AC代码
1 | class Solution { |
实现二:记忆化搜索(二维 + 外层枚举分数)
思路
每次固定一个分数 \(s\)
使用 DFS + 记忆化: \[ dfs(i, j) = f(i, j) \]
对每个候选分数单独跑一次 DFS
AC代码
1 | class Solution { |
六、总结
- 核心建模点:第一次操作决定全局分数,只需枚举 3 种可能;
- 核心状态:区间 \([i, j]\);
- 核心转移:三种删除方式,对应三种区间缩小;
- 两种等价实现:
- 区间 DP:结构清晰,适合自底向上;
- 记忆化搜索:代码直观,贴近数学定义。
这道题的本质是:
“固定目标值下的区间最大删除次数问题”