740[Medium]:Delete and Earn
2017-12-07 12:23
405 查看
Part1:题目描述
Given an arraynumsof 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] - 1or
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
numsis 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; }
相关文章推荐
- 740. Delete and Earn
- 740. Delete and Earn
- 740. Delete and Earn
- 740. Delete and Earn
- 740. Delete and Earn
- LWC 61:740. Delete and Earn
- 740. Delete and Earn
- 【第十五周】740. Delete and Earn
- 740. Delete and Earn
- 740. Delete and Earn
- Leetcode刷题:740. Delete and Earn
- LeetCode | 740. Delete and Earn
- Delete and Earn
- week17-leetcode #740-DeleteandEarn
- 再从萌新开始-Leetcode每日题解-740. Delete and Earn
- 算法练习(32):Delete and Earn
- Delete and Earn
- 740. Delete and Earn
- 740. Delete and Earn【Medium】 动归
- 算法题目--Delete and Earn