【动态规划】陶然无喜亦无忧,人生且自由 - 简单多状态模型

在这里插入图片描述

本篇博客给大家带来的是简单多状态之动态规划解法技巧.
🐎文章专栏: 动态规划
🚀若有问题 评论区见
欢迎大家点赞 评论 收藏 分享
如果你不知道分享给谁,那就分享给薯条.
你们的支持是我不断创作的动力 .

要开心

要快乐

顺便进步

1. 按摩师

题目链接: 面试题 17.16. 按摩师

题目内容:

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

注意:本题相对原题稍作改动

示例 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 位置时, 可由 i 位置是否选择分两种情况:
f[i] 表示选择到 i 位置时 nums[i] 必选的最长时间.
g[i] 表示选择到 i 位置时 nums[i] 不选的最长时间.

2. 状态转移方程

f[i]递推公式分析图

先分析关于f[i]的递推公式, 如上图, nums[i] 必选意味着nums[i-1]必定不选. 从起始点到[i-1]且nums[i-1]不选, 不就是g[i-1]吗?
所以f[i] = g[i-1] + nums[i];

g[i]递推公式分析图

再求g[i] 的递推公式
如上图, nums[i]不选, nums[i-1] 可选可不选.
nums[i-1] 选择时, g[i] = f[i-1]
nums[i-1] 不选时, g[i] = g[i-1]
又因为是求最大值,所以g[i] = Math.max(f[i-1],g[i-1]);

3. 初始化
f[0] = nums[0]

4. 填表顺序
从左往右填表

5. 返回值
返回Math.max(f[n-1],g[n-1]);

第二 代码实现

class Solution {
   
    public int massage(int[] nums) {
   
        //1. 创建dp表
        int n = nums.length;
        int[] f = new int[n];
        int[] g = new int[n];
        //2. 初始化
        if(nums.length == 0) return 0;
        f[0] = nums[0];
        //3. 填表
        for(int i = 1;i < n;++i) {
   
            f[i] = g[i-1] + nums[i];
            g[i] = Math.max(f[i-1],g[i-1]);
        }
        return Math.max(f[n-1],g[n-1]);
    }
}

2. 打家劫舍

评论 144
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值