C/C++ 算法入门:多状态动态规划
引言
动态规划(DP)的核心在于状态定义与转移。当问题涉及多个互斥或关联的状态时,我们需要引入多状态 DP。本章将通过经典的「打家劫舍」系列和「股票买卖」系列问题,由浅入深地讲解如何拆解复杂状态,构建高效的 DP 模型。
打家劫舍基础
在遇到相邻元素不能同时选择的线性问题时,通常可以考虑使用双状态 DP。我们定义两个数组来分别记录当前节点选或不选时的最大收益。
1. 按摩师(LeetCode 面试题 17.05)
题目描述: 给定一个整数数组 nums,表示预约时长。不能连续选择相邻的预约,求最长预约时长。
思路分析:
对于每个位置 i,我们有两种选择:
- 选择 i:那么
i-1必须不选。收益为g[i-1] + nums[i]。 - 不选 i:那么
i-1可选可不选。收益为max(f[i-1], g[i-1])。
其中 f[i] 表示选第 i 个位置的最大值,g[i] 表示不选第 i 个位置的最大值。
代码实现:
class Solution {
public:
int massage(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
vector<int> f(n, 0); // 选择 i 位置
vector<int> g(n, 0); // 不选择 i 位置
f[0] = nums[0];
for (int i = 1; i < n; i++) {
f[i] = g[i - 1] + nums[i];
g[i] = (f[i - ], g[i - ]);
}
(f[n - ], g[n - ]);
}
};


