动态规划-简单多状态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.状态表示

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

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

但是该题中我们对于每个 i 位置都有 "选择" 和 "不选择" 两种方案,所以对 dp[i] 进行细分为 f[i] 和 g[i] :

  • f[i] 表示:选择到 i 位置时,nums[i] 被选择,此时的最长预约时长
  • g[i] 表示:选择到 i 位置时,nums[i] 不被选,此时的最长预约时长

2.状态转移方程

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

对于 f[i]:

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

对于 g[i]:

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

3.初始化

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

  • f[0] = nums[0]
  • g[0] = 0

4.填表顺序

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

从左往右,两表同填

5.返回值

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

max(f[n - 1], g[n - 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]);
    }
};

提交结果:

相关推荐
Mr_Xuhhh37 分钟前
项目需求分析(2)
c++·算法·leetcode·log4j
c++bug1 小时前
六级第一关——下楼梯
算法
PAK向日葵1 小时前
【C/C++】面试官:手写一个memmove,要求性能尽可能高
c语言·c++·面试
Morri31 小时前
[Java恶补day53] 45. 跳跃游戏Ⅱ
java·算法·leetcode
林木辛2 小时前
LeetCode热题 15.三数之和(双指针)
算法·leetcode·双指针
AndrewHZ2 小时前
【3D算法技术】blender中,在曲面上如何进行贴图?
算法·3d·blender·贴图·三维建模·三维重建·pcg
Jared_devin2 小时前
二叉树算法题—— [蓝桥杯 2019 省 AB] 完全二叉树的权值
数据结构·c++·算法·职场和发展·蓝桥杯
搞全栈小苏2 小时前
基于Qt QML和C++的MQTT测试客户端(CMakeLists实现)
xml·c++·qt
啊?啊?2 小时前
18 从对象内存到函数调用:C++ 虚函数表原理(继承覆盖 / 动态绑定)+ 多态实战
开发语言·c++·多态原理
bkspiderx2 小时前
C++标准库:文件流类
开发语言·c++