740. Delete and Earn
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 ofnums
is at most
20000
.Each element
nums[i]
is an integer in the range
[1, 10000]
.
----------------------------------分割线-----------------------------------------
题目给出一组数(有重复数组),让你选择一个数n,所有这个数的和作为你的分数累加(比如说选择5,数组里面有3个5,分数为3*5 = 15),然后将这个数n以及n+1,n-1从数组里面剔除。重复以上,问能得到的最高分。
分析:
一道dp,瞄一眼数据量,数最大为2w,最多1w个数,使用int已经足够了。写一下状态转移方程:
dp[i] = max(dp[i+1]+point[i] , dp[i+2]+point[i]); (dp[i+1] - dp[i] != 1)
dp[i] = max(dp[i+1], dp[i+2]+point[i]); (dp[i+1] - dp[i] == 1)
前提是做好数组去重以及按照升序排列,顺便把point给计算出来。
dp[i]相当于到第i个数所得到的分数总和,point[i]是选择第i个数能够获得的分数。
代码:
class Solution{
public:
int deleteAndEarn(vector<int>& nums){
vector<int> num;
vector<int> point;
int len = nums.size();
sort(nums.begin(),nums.end());
for (int i = 0 ; i < len ; i++){
if (i && nums[i] == num.back()) point.back() += nums[i];
else{
point.push_back(nums[i]);
num.push_back(nums[i]);
}
}
len = num.size();
num.push_back(0);
num.push_back(0);
int* dp = new int [len+2];
dp[len+1] = dp[len] = 0;
for (int i = len-1 ; i >= 0 ; i--){
if (num[i+1] - num[i] == 1)
dp[i] = max(dp[i+1], dp[i+2]+point[i]);
else dp[i] = max(dp[i+1]+point[i], dp[i+2]+point[i]);
}
return dp[0];
}
};
---------------------------分割线----------------------------------
其他人的思路有一点不同,他们用dp[i]表示不大于x的数字获得到最大得分,用cnt[i]来记录数字i的个数。
相当于用一个桶来简化了dp方程,方程如下:
dp[i] = max (dp[i-1], dp[i-2] + cnt[i]*i)
对于本题的数据大小是绝对没问题的,而且好理解一点。