您的位置:首页 > 编程语言 > C语言/C++

740[Medium]:Delete and Earn

2017-12-07 12:23 405 查看

Part1:题目描述

Given an array 
nums
 of integers, you can perform operations on the array.

In each operation, you pick any 
nums[i]
 and delete it to earn 
nums[i]
 points.
After, you must delete every element equal to 
nums[i] -
1
 or 
nums[i] + 1
.

You start with 0 points. Return the maximum number of points you can earn by applying such operations.

Example 1:

Input: nums = [3, 4, 2]
Output: 6
Explanation:
Delete 4 to earn 4 points, consequently 3 is also deleted.
Then, delete 2 to earn 2 points. 6 total points are earned.


Example 2:

Input: nums = [2, 2, 3, 3, 3, 4]
Output: 9
Explanation:
Delete 3 to earn 3 points, deleting both 2's and the 4.
Then, delete 3 again to earn 3 points, and 3 again to earn 3 points.
9 total points are earned.


Note:

The length of 
nums
 is at most 
20000
.
Each element 
nums[i]
 is an integer in the range 
[1,
10000]
.


Part2:解题思路
  动态规划的题目能够想出动态规划的方程真的是很关键的第一步,可是很难过我现在还没能成功自己找出过动态规划方程,但是我会不断积累经验的!这道题目我是看了leetcode上的soluton上的解题思路做的,现在再用我自己的语言总结一下,当作巩固吧。

  对于每一个nums[i],都有选和不选2种可能,当前的选择结果值也会以同样的方式影响下一步,这也正是能用动态规划的地方,可以化成一小步一小步的解决。

  所以我们需要记录会对下一步造成影响的当前的所有值:

  previous:当前这一步选择的值。nums[i+1]与之是否相邻,会影响选择nums[i+1]之后used和avoid值的结果。相邻选择nums[i+1],used = avoid+nums[i+1];不相邻选择nums[i+1],used = max(avoid, used)(这里的avoid, used的值是上一步中的)+nums[i+1];

  used:选择当前nums[i]之后的总point

  avoid:不选择当前nums[i]之后的总point

  最终我们要求的也应该是max(avoid, used),因为到vector里的最后一个元素时,我们也不能保证选他和不选他谁的值最大,所以我们要取二者的最大值。

补充说明:

虽然题目描述中说,选了nums[i]之后nums[i-1]和nums[i+1]都不能选择,但是我们排序之后限制选了nums[i]之后nums[i + 1]就不能选结果也是一样的。

Part3:代码

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int deleteAndEarn(vector<int>& nums) {
int length = nums.size();
int used = 0, avoid = 0, previous = 0;
if (length == 0) return 0;
sort(nums.begin(), nums.end());

for (int i = 0; i < length; i++) {
int temp = max(used, avoid);
if ((i != 0) && (nums[i - 1] == nums[i])) {
used += nums[i];
}
else if (previous + 1 == nums[i]) {
used = avoid + nums[i];
avoid = temp;
} else {
used = temp + nums[i];
avoid = temp;
}
previous = nums[i];
}

return max(used, avoid);
}

int main() {
int num;
cin >> num;
vector<int>nums;
for (int i = 0; i < num; i++) {
int temp;
cin >> temp;
nums.push_back(temp);
}
cout << deleteAndEarn(nums) << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 动态规划