程序员面试金典 17.16 按摩师 (Java版; 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。
第一次做; 动态规划, 时间复杂度O(N) 核心:1)注意dp[i]的含义和返回值之间的关系 2)递推公式dp[i]和dp[i-?], 以及需要几个dp[i-?]都是需要明确的
class Solution {
public int massage ( int [ ] nums) {
int n = nums. length;
if ( n== 0 ) {
return 0 ;
}
int [ ] [ ] dp = new int [ n] [ 2 ] ;
dp[ 0 ] [ 0 ] = 0 ;
dp[ 0 ] [ 1 ] = nums[ 0 ] ;
for ( int i= 1 ; i< n; i++ ) {
dp[ i] [ 0 ] = Math. max ( dp[ i- 1 ] [ 0 ] , dp[ i- 1 ] [ 1 ] ) ;
dp[ i] [ 1 ] = dp[ i- 1 ] [ 0 ] + nums[ i] ;
}
return Math. max ( dp[ n- 1 ] [ 0 ] , dp[ n- 1 ] [ 1 ] ) ;
}
}
第一次做; 动态规划, 时间复杂度O(N^2) 核心: 1)dp[i]表示以nums[i]结尾时的最长预约时间; 计算dp[i]时必须以nums[i]结尾, 否则就没法计算状态转移了 2)注意dp[i]的含义和返回值之间的关系!注意dp[i]的含义和返回值之间的关系!注意dp[i]的含义和返回值之间的关系! 不要无脑返回dp[n-1]
class Solution {
public int massage ( int [ ] nums) {
if ( nums== null || nums. length== 0 ) {
return 0 ;
}
int n = nums. length;
int [ ] dp = new int [ n] ;
int max = dp[ 0 ] ;
for ( int i= 0 ; i< n; i++ ) {
dp[ i] = nums[ i] ;
for ( int j= 0 ; j< i- 1 ; j++ ) {
dp[ i] = Math. max ( dp[ i] , dp[ j] + nums[ i] ) ;
}
max = Math. max ( max, dp[ i] ) ;
}
return max;
}
}