题意
一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
示例 1:
1 | 输入: [1,2,3,1] |
示例 2:
1 | 输入: [2,7,9,3,1] |
示例 3:
1 | 输入: [2,1,4,5,3,1,1,3] |
思路
定义 $dp[i]$ 表示以 $i$ 号预约结尾时的最大服务时长。
首先注意到一定存在 $dp[i] \ge dp[i-2]$ ,因为若 $dp[i]$ 中选择 $i-2$ 号预约时,将有 $dp[i]=dp[i-2]+nums[i]$ 。
此外,当选择了 $i$ 号预约后,$i-1$ 号预约将无法被选择,根据上面结论,$dp[i-2] \ge dp[i-4]$, $dp[i-3] \ge dp[i-5]$,因此状态转移方程为:
注意边界条件,$dp[0]=0$,$dp[i] = nums[i]\space(i \le 2)$。
最终的答案为 $max(dp[n], dp[n-1])$ ,其中 $n$ 为序列长度。因为整个序列的最大服务时长序列中要么包括 $n$ 号预约,要么不包括。
代码如下:
1 | class Solution { |
此处时间复杂度和空间复杂度均为 $O(n)$ ,由于我们只需要 $dp[n]$ 和 $dp[n-1]$ ,且每个状态的计算最多只涉及到前3项,因此可以用变量代替数组,空间复杂度降低为 $O(1)$ 。