动态规划入门:多状态 DP 问题实战
在掌握基础的一维和二维 DP 后,我们进入多状态 DP 的学习。本章将从简单的打家劫舍两状态 DP 入手,逐步过渡到股票问题的四状态 DP,通过实战练习巩固核心框架。
打家劫舍系列
遇到相邻元素不能同时选择的场景时,通常可以考虑使用打家劫舍模型。核心思路是维护两个状态数组:
f[i]:选择第 i 个位置时的最大价值。g[i]:不选择第 i 个位置时的最大价值。
按摩师
题目描述: 给定一个整数数组表示预约时长,不能连续选择相邻的预约,求最长预约时长。
分析思路: 这是一个典型的线性 DP 问题。对于每个位置,只有两种状态:选或不选。
- 状态定义:
dp[i][0]:选择第 i 个预约的最大时长。dp[i][1]:不选择第 i 个预约的最大时长。
- 状态转移:
- 若选择 i,则 i-1 必须不选:
dp[i][0] = dp[i-1][1] + nums[i] - 若不选 i,则 i-1 可选可不选:
dp[i][1] = max(dp[i-1][0], dp[i-1][1])
- 若选择 i,则 i-1 必须不选:
- 初始化:
dp[0][0] = nums[0],dp[0][1] = 0
- 返回值:
max(dp[n-1][0], dp[n-1][1])
代码实现:
class Solution {
public:
int massage(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
// f: 选择当前位置, g: 不选择当前位置
vector<int> f(n), g(n);
f[0] = nums[0];
g[0] = 0;
for ( i = ; i < n; ++i) {
f[i] = g[i - ] + nums[i];
g[i] = (g[i - ], f[i - ]);
}
(f[n - ], g[n - ]);
}
};


