动态规划-简单多状态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]);
    }
};

提交结果:

相关推荐
MC皮蛋侠客1 天前
Google Test 单元测试指南
c++·单元测试·google test
艾莉丝努力练剑1 天前
【Linux:文件】Ext系列文件系统进阶
linux·运维·服务器·c++·文件系统·文件io·ext
kkeeper~1 天前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
wabs6661 天前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_876964131 天前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
basketball6161 天前
C++ NULL 和 nullptr 区别 以及 nullptr 的核心实现
java·开发语言·c++
嗝o゚1 天前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本1 天前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
Fre丸子_1 天前
自定义文件夹选取功能
c++
Ulyanov1 天前
用声明式语法重新定义Python桌面UI:QML+PySide6现代开发入门(一)
开发语言·python·算法·ui·系统仿真·雷达电子对抗仿真