动态规划详解(四):线性DP原理深度剖析
目录
一、线性DP的本质与核心地位
二、线性DP的三大特征
三、线性DP的四种经典类型
四、解题方法论:五步破解线性DP
1. 状态定义
2. 转移方程
3. 初始化
4. 遍历顺序
5. 结果提取
五、经典案例详解
1. 最长上升子序列(LIS)
问题描述
Java实现
优化技巧
2. 最长公共子序列(LCS)
问题描述
Java实现
空间优化
3. 最大子数组和(Kadane算法)
问题描述
Java实现
算法分析
六、高频问题变形:带维度的线性DP
1. 买卖股票的最佳时机(含冷冻期)
状态定义
Java实现
七、线性DP优化技巧
1. 滚动数组压缩
2. 状态机优化
3. 前缀和加速
八、LeetCode实战训练
基础练习
进阶挑战
九、常见错误与调试技巧
十、总结
一、线性DP的本质与核心地位
线性动态规划(Linear DP) 是动态规划中最基础但应用最广泛的类型,其特点是状态转移沿着线性维度展开。在LeetCode等算法平台中,超过40%的动态规划问题属于线性DP范畴。掌握线性DP的解题范式,是打开动态规划大门的金钥匙。
二、线性DP的三大特征
-
单维度状态转移:状态转移仅沿单一方向递推
-
无后效性:当前状态仅依赖前序状态,与后续状态无关
-
状态紧凑:通常用一维或二维数组存储状态
三、线性DP的四种经典类型
类型 | 典型问题 | 状态维度 | 转移方向 |
---|---|---|---|
单串线性DP | 最长上升子序列(LIS) | 一维 | 前向扫描 |
双串线性DP | 最长公共子序列(LCS) | 二维 | 双串同步扫描 |
矩阵线性DP | 最小路径和 | 二维 | 矩阵逐行扫描 |
带维度线性DP | 买卖股票的最佳时机(带次数限制) | 三维 | 状态机转移 |
四、解题方法论:五步破解线性DP
1. 状态定义
明确语义:
dp[i]
或dp[i][j]
的具体含义示例:
LIS问题:
dp[i]
表示以nums[i]
结尾的最长上升子序列长度LCS问题:
dp[i][j]
表示text1[0..i]
与text2[0..j]
的最长公共子序列长度
2. 转移方程
找出状态间关系:分析当前状态如何从前序状态推导
示例:
LIS转移方程:
dp[i] = max(dp[j]) + 1 (0 ≤ j < i且nums[j] < nums[i])
3. 初始化
设置起点状态:通常初始化
dp[0]
或边界条件示例:
最小路径和:
dp[0][0] = grid[0][0]
4. 遍历顺序
确定计算方向:根据状态依赖关系选择正序/逆序
示例:
单串DP通常正序遍历
某些问题需要逆序(如滚动数组优化)
5. 结果提取
从状态数组中获取答案:最大值、最小值或特定位置值
示例:
LIS最终结果:
max(dp[i])