740. Delete and Earn

来源:互联网 发布:java递归求n的阶乘 编辑:程序博客网 时间:2024/05/18 04:40

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 tonums[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].


  • 给一个数组,按照规则:取一个数n累加,同时n的左右(n-1和n+1)删除;求累加数的最大值。很容易想到的是,如果取了一个数n,那么等于n的数也要取上才有可能得到最大。所以先用map将同数值的数先累加,键为数值,值为同数值的总值。然后用动态规划的思想,用两个数值max1和max2,分别代表取当前的数和不取当前的数得到的最大和。如果取当前的数,则要看前一个数是不是邻近的数,如果是,则max1更新为原max2加上当前数的总值(也就是不用前一个数);如果不是,则max1更新为max1和max2的最大值加上当前数的总值。


    代码:

    class Solution {public:    int deleteAndEarn(vector<int>& nums) {        map<int, int> m;        sort(nums.begin(), nums.end());        for(auto n:nums) {            m[n] += n;        }        int max1 = 0, max2 = 0;         map<int, int>::iterator p;        for(auto i = m.begin(); i != m.end(); ++i) {            if(i == m.begin()) {                max1 = i->second;                max2 = 0;            }            else {                int pmax1 = max1, pmax2 = max2;                max2 = max(pmax1, pmax2);                if(i->first == p->first+1) {                    max1 = pmax2 + i->second;                }                else {                    max1 = max2 + i->second;                }            }            p = i;            // cout << max1 << " " << max2 << endl;        }        return max(max1, max2);    }};



    原创粉丝点击