3693. 爬楼梯 II
考点
- 线性DP
思路
一、问题概述
给定一个正整数 \(n\),表示需要从第 \(0\) 级台阶走到第 \(n\) 级台阶。 每次可以选择向前迈 1、2 或 3 级台阶,但不同步数对应不同的代价规则:
迈 1 级:需要支付 \[ \text{costs}[i] + 1 \]
迈 2 级:需要支付 \[ \text{costs}[i+1] + 4 \]
迈 3 级:需要支付 \[ \text{costs}[i+2] + 9 \]
其中 \(i\) 表示当前所处的台阶编号(从 0 开始)。
目标是:求到达第 \(n\) 级台阶的最小总代价。
二、状态定义
定义一维动态规划数组: \[ f[i] = \text{到达第 } i \text{ 级台阶的最小总代价} \] 这是一个典型的最短路径型 DP,每个状态只依赖于更小编号的状态。
三、初始条件
起点位于第 \(0\) 级台阶,不需要任何代价: \[ f[0] = 0 \]
其余状态初始化为一个足够大的值(表示尚不可达): \[ f[i] = +\infty \quad (i > 0) \]
四、状态转移方程(重点)
假设当前已经处在第 \(i\) 级台阶,且 \(f[i]\) 已经是最优值,则可以进行如下三种转移:
1. 向前迈 1 级
若 \(i + 1 \le n\),则: \[ f[i+1] = \min\bigl(f[i+1],\ f[i] + \text{costs}[i] + 1\bigr) \]
2. 向前迈 2 级
若 \(i + 2 \le n\),则: \[ f[i+2] = \min\bigl(f[i+2],\ f[i] + \text{costs}[i+1] + 4\bigr) \]
3. 向前迈 3 级
若 \(i + 3 \le n\),则: \[ f[i+3] = \min\bigl(f[i+3],\ f[i] + \text{costs}[i+2] + 9\bigr) \]
五、转移顺序与正确性说明
台阶编号是严格递增的,因此可以按照 \[ i = 0 \rightarrow n-1 \] 的顺序进行状态转移。
每个状态只依赖于编号更小的状态,满足 无后效性。
所有可能到达某个台阶的路径都会在转移过程中被枚举到,因此最终的 \(f[n]\) 一定是全局最优解。
六、空间优化思想
观察状态转移可知:
\(f[i]\) 只会影响 \[ f[i+1],\ f[i+2],\ f[i+3] \]
不需要保存完整的 DP 数组,只需维护一个长度为 4 的“滑动窗口”。
可以使用滚动变量:
cur:当前 \(f[i]\)f1:未来的 \(f[i+1]\)f2:未来的 \(f[i+2]\)f3:未来的 \(f[i+3]\)
每次循环后整体向前平移,从而将空间复杂度从 \(O(n)\) 优化为 \(O(1)\)。
七、时间与空间复杂度
时间复杂度: \[ O(n) \] 每个台阶只进行常数次转移。
空间复杂度:
- 普通 DP:\(O(n)\)
- 滚动优化:\(O(1)\)
八、AC代码
版本一:标准一维 DP(易理解)
1 | class Solution { |
版本二:滚动变量优化(\(O(1)\) 空间)
1 | class Solution { |