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

提交结果:

相关推荐
saltymilk15 小时前
C++ 模板参数推导问题小记(模板类的模板构造函数)
c++·模板元编程
感哥16 小时前
C++ lambda 匿名函数
c++
沐怡旸1 天前
【底层机制】std::unique_ptr 解决的痛点?是什么?如何实现?怎么正确使用?
c++·面试
感哥1 天前
C++ 内存管理
c++
聚客AI1 天前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
大怪v1 天前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
惯导马工1 天前
【论文导读】ORB-SLAM3:An Accurate Open-Source Library for Visual, Visual-Inertial and
深度学习·算法
骑自行车的码农1 天前
【React用到的一些算法】游标和栈
算法·react.js
博笙困了1 天前
AcWing学习——双指针算法
c++·算法
感哥1 天前
C++ 指针和引用
c++