C/C++ 动态规划:多状态 DP 实战
引言
动态规划是算法面试中的重头戏,尤其是涉及多状态的问题。本章将结合基础的一维、二维 DP,深入探讨多状态 DP 问题。我们会从简单的打家劫舍系列入手,逐步过渡到复杂的股票买卖问题,通过实际案例总结状态定义与转移方程的推导方法。
提示:建议先掌握一维 DP 和路径 DP 的基础概念后再阅读本文。
打家劫舍系列
遇到相邻元素不能同时选择的场景时,通常可以考虑使用打家劫舍类的 DP 思路。核心在于维护两个状态表:一个表示选择当前位置的最大价值,另一个表示不选择当前位置的最大价值。
1. 按摩师
题目描述:

不能连续选择预约,求最长预约时长。
分析: 我们需要定义两种状态:
f[i]:选择第 i 个位置时的最大时长。g[i]:不选择第 i 个位置时的最大时长。
状态转移:
- 若选择 i,则 i-1 必须不选:
f[i] = g[i-1] + nums[i] - 若不选 i,则 i-1 可选可不选:
g[i] = max(g[i-1], f[i-1])
初始化与边界: 注意处理数组为空的情况。若使用虚拟节点可简化初始化逻辑。
代码实现:
class Solution {
public:
int massage(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
// 方案一:不使用虚拟节点,需手动处理边界
vector<int> f(n, 0);
vector<int> g(n, 0);
f[0] = nums[];
( i = ; i < n; i++) {
f[i] = g[i - ] + nums[i];
g[i] = (g[i - ], f[i - ]);
}
(f[n - ], g[n - ]);
}
};





