740. 删除并获得点数

思路:
当获取x后,x+1和x-1大小的元素不能再取,我们得到的点数为x*x的个数。
因此我们需要记录每个nums元素的个数,同时获得排序后的nums中出现过的元素,只要一个,用来判断上次取的数和这次取的数是否差为1或-1。
我们用hash表count来记录元素出现的次数,用dp数组存放出现过的元素,因为我们需要用这个元素值乘出现的次数,所以直接在dp存即可。

先把状态转移方程列出来
如果 当前取出的值和上一次取的值差为+-1,那么方程为:
dp[i] = max(dp[i-1],dp[i-2]+dp[i]count[dp[i]]
因为如果差为+-1,我们就不能同时取上一个值和当前的值,那么我们就计算上次的计算出的点数dp[i-1]是否大于dp[i-2]+dp[i]
count[dp[i]]的点数,然后取最大的,作为这次动规的结果。i-2 是因为已经排序,且每个元素只有1个,所以nums[i-2]个不会和nums[i]差为+-1
当差不为+-1时,方程为:
dp[i] = dp[i-1]+dp[i]*count[dp[i]];
不为+-1,那么就直接累加即可。

代码:

class Solution {
public:
    int deleteAndEarn(vector<int>& nums) {
        unordered_map<int,int> count;
        sort(nums.begin(),nums.end());
        vector<int> dp={0,nums[0]};
        
        for(int num:nums){
            count[num]++;
            if(num != dp.back()) dp.push_back(num);
        }
        int n = dp.size(); 
        int last=dp[1];  //记录上一次取的元素的大小
        dp[1]=dp[1]*count[dp[1]];
        for(int i=2;i<dp.size();++i){
            if(abs(dp[i]-last)==1){
                last = dp[i];
                dp[i] = max(dp[i-1],dp[i-2]+dp[i]*count[dp[i]]);
            }
            else{
                last = dp[i];
                dp[i] = dp[i-1] + dp[i]*count[dp[i]];
            }
        }
        return dp[n-1];
    }
};
posted @ 2021-05-13 19:02  Mrsdwang  阅读(52)  评论(0编辑  收藏  举报