一、问题描述

一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。

给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。

题目链接:按摩师

二、题目要求

样例

输入: [2,7,9,3,1]
输出: 12
解释: 选择 1 号预约、 3 号预约和 5 号预约,总时长 = 2 + 9 + 1 = 12。

考察

1.动态规划中等题型
2.建议用时15~30min

三、问题分析

这一题和算法题每日一练---第37天:打家劫舍本质上差不多,之前做过第37天练习的,可以看看这一题重温一下相关知识点。

毕竟是动态规划,还是老老实实用我们的三步走,老套路了:

第一步 含义搞懂:

按摩师在有休息间隔的情况下,如何赚取更多的钱。

那么dp[i]就代表下标0~i这段时间内,赚取的最大金额。

第二步 变量初始:

以上面的样例为例:

dp[0]=nums[0]     只有一个客人,所以只能选择这一个了
dp[1]=max(nums[0],nums[1])     当只有两个客人时,出价最高者得

第三步 规律归纳:

那么dp[i]和前面的关系如何呢? 有两种选择:

1.不选择当前的客户,而是选择前一个顾客   dp[i-1]
2.选择当前的客户,前一个顾客不能选了,要隔2个     nums[i]+dp[i-2]

那么这两种选择,只要判断哪一种选择赚的钱更多不就行了,规律如下:

dp[i]=max(nums[i]+dp[i-2],dp[i-1]);

三步走,打完收工!

四、编码实现

class Solution {
public:
    int massage(vector<int>& nums) {
        int i,n=nums.size();//初始化定义
        int dp[n+1];
        if(n==0)    return 0;//没人预约
        if(n==1)    return nums[0];//只有一个人预约
        dp[0]=nums[0];//变量初始
        dp[1]=max(nums[0],nums[1]);//变量初始
        for(i=2;i<n;i++)
        {
            dp[i]=max(nums[i]+dp[i-2],dp[i-1]);//规律归纳
        }
        return dp[n-1];//输出结果
    }
};

五、测试结果

1.png

2.png