按摩师(easy)
题目链接:
题目描述:
一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
**注意:**本题相对原题稍作改动
示例 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。
题目解析
这道题目时这样的,我们得到一系列预约,每个预约都要花费一些时间,我们如何选让我们工作的时间更多,毕竟钱比较多吗.不过接收预约是有一定的规则的,例如我们接收了一个预约,那么此时下一个预约我不能接收了,毕竟我要休息.
算法原理
状态表示
按照经验,我们以...为结尾表示状态.
dp[i]:表示以i位置为结尾,我们可以等到更多的时间,不过此时我们需要知道是,在i位置,我们可以选这个预约,也可以不选这个预约.此时我们可以定义两个状态.
f[i]: 表示以i位置为结尾,我们接收i位置的预约,可以等到更多的时间.
g[i]: 表示以i位置为结尾,我们不接收i位置的预约,可以等到更多的时间.
状态转移方程
f[i]: 如果我们想要接收i位置,那么i-1位置不可以接收, f[i] = g[i-1]+v[i]
g[i]: 不接受i位置,那么i-1位置可以接收,也可以不接受 g[i] = max(f[i-1], g[i-1]);
初始化
借助了i-1位置,那么此时我们多加上一个节点,这里需要注意的,我们给f[0] = 0,g[0] = 0.
填表顺序
从左向由填,此时一起填.
返回值
返回f[n]和g[n]的最大值
编写代码
class Solution {
public:
int massage(vector<int>& nums) {
int n = nums.size();
vector<int> f(n+1, 0);
vector<int> g(n+1, 0);
for(int i = 1; i <= n; i++)
{
f[i] = g[i-1] + nums[i-1];
g[i] = max(f[i-1], g[i-1]);
}
return max(f[n], g[n]);
}
};
标签:面试题,12,预约,位置,我们,17.16,接收,按摩师
From: https://blog.51cto.com/byte/7401035