Leetcode 面试题 17.16. 按摩师 C语言
问题描述
一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
示例一
输入: [1,2,3,1]
输出: 4
解释: 选择 1 号预约和 3 号预约,总时长 = 1 + 3 = 4。
示例二
输入: [2,7,9,3,1]
输出: 12
解释: 选择 1 号预约、 3 号预约和 5 号预约,总时长 = 2 + 9 + 1 = 12。
示例三
输入: [2,1,4,5,3,1,1,3]
输出: 12
解释: 选择 1 号预约、 3 号预约、 5 号预约和 8 号预约,总时长 = 2 + 4 + 3 + 3 = 12。
简要分析
对于一般情况(数组中的元素大于等于2),前两个元素必有一个在最后结果的和中。我们可以创建一个数组 ans,它的第 i 项等于序列数组 nums 前 i 项的最优结果,显然 ans[0] 等于 nums [0],ans[1] 等于 nums[0] 和 nums[1] 中较大数。对于 ans 中的第 i 项,我们中需要考虑 nums 中的第 i 项在不在其和之中,我们可以通过比较 ans[ i-2 ] + nums[ i ] 与ans[ i-1 ] 的大小来判断,因为,其一,ans[ i-2] 中一定不包含 nums[ i-1 ],这不影响 ans[ i-2 ] 与 nums[ i ] 相加;其二,若 ans[ i-1 ] 中包含 nums[ i-1] 则 ans[ i-1 ] 不能与 nums[ i ] 相加,若 ans[ i-1 ] 中不包含 nums[ i-1] 则 ans[ i-1 ] 与 ans[ i-2 ] 相等,那么 ans[ i-2 ] + nums[ i ] 一定大于 ans[ i-1 ]。
代码如下
int massage(int* nums, int numsSize)
{
if(numsSize == 0)
{
return 0;
}
if(numsSize == 1)
{
return *nums;
}
else
{
int ans[2], temp;
int *p;
ans[0] = *nums;
if(nums[1] > nums[0])
{
ans[1] = nums[1];
}
else
{
ans[1] = nums[0];
}
for(p = nums + 2; p < nums + numsSize; p++)
{
if(ans[0] + *p > ans[1])
{
temp = ans[1];
ans[1] = ans[0] + *p;
ans[0] = temp;
}
else
{
ans[0] = ans[1];
}
}
return ans[1];
}
}