动态规划-简单多状态dp问题 -- 按摩师

动态规划-简单多状态dp问题 -- 按摩师

文章目录

题目重现

题目链接:按摩师 - 力扣

一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接 。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约 。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
示例 1:

复制代码
输入: [1,2,3,1]
输出: 4
解释: 选择 1 号预约和 3 号预约,总时长 = 1 + 3 = 4。

示例 2:

复制代码
输入: [2,7,9,3,1]
输出: 12
解释: 选择 1 号预约、 3 号预约和 5 号预约,总时长 = 2 + 9 + 1 = 12。

示例 3:

复制代码
输入: [2,1,4,5,3,1,1,3]
输出: 12
解释: 选择 1 号预约、 3 号预约、 5 号预约和 8 号预约,总时长 = 2 + 4 + 3 + 3 = 12。

算法流程

1.状态表示

这里我们选用较为常用的方式:以某个位置为结尾,定义一个状态表示:

dpi 表示:选择到 i 位置时,此时的最长预约时长

但是该题中我们对于每个 i 位置都有 "选择" 和 "不选择" 两种方案,所以对 dpi 进行细分为 fi 和 gi

  • fi 表示:选择到 i 位置时,numsi 被选择,此时的最长预约时长
  • gi 表示:选择到 i 位置时,numsi 不被选,此时的最长预约时长

2.状态转移方程

由于往常状态表示只有一个,状态转移方程也只有一个,但是如今有两个状态表示 f 和 g,所以状态转移方程应当也有两个:

对于 fi

  • 如果 numsi 被选择,那么 numsi - 1 就必然没有被选择,因为被选中的元素所在位置不能是相邻的。那么 gi - 1 刚好表示 i - 1 位置未被选择情况下,截止 i - 1 位置最长的预约时长。从而该位置被选择的情况下,相应的 fi = gi - 1 + numsi

对于 gi

  • 如果 numsi 没有被选择,那么 numsi - 1 就存在两种可能,即被选和未被选两种。对于 i 位置而言,仅考虑 i - 1 位置对应的最长时长,而不是 i - 1 位置是否被选中,所以 gi = max(fi - 1, gi - 1)

3.初始化

既然我们已经得到对于每个 i 位置的状态转移方程,那么我们就不难看出每个 i 节点的状态 fi 和 gi 都离不开 i - 1 位置的状态值。所以我们结合题意和状态表示,给出 i = 0 位置的初始化:

  • f0 = nums0
  • g0 = 0

4.填表顺序

通过 < 3.初始化 > 中的描述得知,填表顺序为:

从左往右,两表同填

5.返回值

根据状态表示,i 位置对应的值即为最长预约时间,又因为其有两种状态(被选择和未被选),所以返回值为:

max(fn - 1, gn - 1)

示例代码

cpp 复制代码
class Solution {
public:
    int massage(vector<int>& nums) {
        int n = nums.size();
        if(n == 0) { return 0; }
        vector<int> f(n);   // 选nums[i], 最大分钟数
        auto g = f;   // 不选nums[i], 最大分钟数

        f[0] = nums[0];
        g[0] = 0;

        for(int i = 1; i < n; i++)
        {
            f[i] = g[i - 1] + nums[i];
            g[i] = max(f[i - 1], g[i - 1]);
        }

        return max(f[n - 1], g[n - 1]);
    }
};

提交结果:

相关推荐
JieE2128 小时前
LeetCode 101. 对称二叉树|JS 递归 + 迭代双解法,彻底搞懂镜像判断
javascript·算法
JieE2121 天前
LeetCode 56. 合并区间|超清晰 JS 图解思路,面试高频区间题
javascript·算法·面试
Jack202 天前
HarmonyOS开发中错误处理策略:网络异常统一处理
算法
小小杨树2 天前
读懂色彩:拍照调色不再难
算法·计算机视觉·配色
JieE2122 天前
LeetCode 226. 翻转二叉树|JS 递归超详细拆解,二叉树入门经典题
javascript·算法
JieE2122 天前
LeetCode 104. 二叉树的最大深度|递归思路超详细拆解
javascript·算法
vivo互联网技术3 天前
CVPR 2026 | 全新强化学习框架 BeautyGRPO:重塑真实人像
算法·大模型·cvpr·影像
Darling噜啦啦3 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
clint4563 天前
C++进阶(1)——前景提要
c++