面试题 17.16. 按摩师

题目:一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数
解法:动态规划
思路:数学符号:dp[i]表示到达位置i的最长时间;状态转移方程:对于任意一个>=3的i,dp[i] = Math.max(dp[i-2],dp[i-3])+nums[i](或者说dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);
代码:
class Solution {
public int massage(int[] nums) {
if(nums.length0){
return 0;
}
if(nums.length
1){
return nums[0];
}
if(nums.length==2){
return Math.max(nums[0],nums[1]);
}
int len = nums.length;
int[] dp = new int[len]; //dp[i]表示到达位置i的最长时间
dp[0] = nums[0];
dp[1] = nums[1];
dp[2] = nums[0]+nums[2];
for(int i=3;i<len;i++){
dp[i] = Math.max(dp[i-2],dp[i-3])+nums[i];
}
return Math.max(dp[len-1],dp[len-2]); //最后的结果肯定包含nums[len-1]或nums[len-2]
}
}

优化空间复杂度:
class Solution {
public int massage(int[] nums) {
if(nums.length0){
return 0;
}
if(nums.length
1){
return nums[0];
}
if(nums.length==2){
return Math.max(nums[0],nums[1]);
}
int len = nums.length;
int a = nums[0];
int b = nums[1];
int c = nums[0]+nums[2];
for(int i=3;i<len;i++){
int max = Math.max(a,b)+nums[i];
a=b;
b=c;
c=max;
}
return Math.max(b,c);
}
}

思路二:数学符号:定义dp[i][0],dp[i][1],其中dp[i][0]表示第i个不接,dp[i][1]表示第i个接;状态转移方程:dp[i][0]=max(dp[i−1][0],dp[i−1][1]),dp[i][1]=dp[i−1][0]+nums[i],最后答案即为max(dp[n][0],dp[n][1])

posted @ 2020-11-15 16:16  for_ward  阅读(114)  评论(0)    收藏  举报