740[Medium]:Delete and Earn

来源:互联网 发布:java 兼职 编辑:程序博客网 时间:2024/06/08 10:57

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: 6Explanation: 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: 9Explanation: 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;}
  • 原创粉丝点击