leetcode动态规划之按摩师,打家劫舍系列

题目

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

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

示例 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。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/the-masseuse-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

动态规划解题思路

leetcode中的按摩师和打家劫舍系列题目其实都是用到了动态规划来解题。本文我们分析按摩师题目如何使用动态规划来分析解题。另外本题的官方题解也说明得很详细,推荐查看。

我们用dp[i]来表示前i个预约的最长预约时间,由于预约之间必须间隔,所以第i个预约按摩师可能是不接,也可能是接。那么我们按照分类情况,使用dp[i][0]表示第i个预约不接的前i个预约的最长预约时间,dp[i][1]表示第i个预约接收的前i个预约的最长预约时间。

接下来我们考虑dp[i][0]的最大值,由于第i个预约不接,所以第i-1个预约接不接都行。

dp[i][0] = max(dp[i-1][0],dp[i-1][1])
//伪代码,go中没有max函数

那么对于dp[i][1]来说,由于第i个预约接收,所以第i-1个预约一定不接收

dp[i][1] = dp[i-1][0]+nums[i]

因此,我们最后获得的按摩师最长预约时间是

max(dp[n][o],dp[n][1])
//伪代码,go中没有max函数

Go版本代码

leetcode动态规划之按摩师,打家劫舍系列_第1张图片

func massage(nums []int) int {
    if len(nums)==0 {
        return 0
    }
    dp0,dp1 := 0,nums[0]
    for i:=1;i<len(nums);i++ {
        var tdp0 int
        var tdp1 int
        if dp0>dp1 {
            tdp0 = dp0//获取i预约不接的最长预约时间
        } else {
            tdp0 = dp1
        }
        tdp1 = dp0 + nums[i]//获取i预约接受的最长预约时间
        
        dp0 = tdp0//更新i预约不接的最长预约时间
        dp1 = tdp1//更新i预约接受的最长预约时间
    }
    if dp0>=dp1 {
        return dp0
    } else {
        return dp1
    }
}

总结

1 动态规划需要把前i个最符合标准的情况统筹考虑,需要设定第i项的动作的是与否。
2 动态规划是常考的算法之一,我们可以通过像本文这样的专项练习,来熟练掌握该算法。
3 继续获得双百分的我感觉自己棒棒哒!

你可能感兴趣的:(leetcode)