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 everyelement 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 of
nums
is at most20000
. - Each element
nums[i]
is an integer in the range[1, 10000]
.
题目大意:https://leetcode.com/problems/delete-and-earn/
题目分析:若取某个数字,必然会全取,设val[i]为数字i的总和,设dp[i][0/1]表示到数字i,不取/取时的最大值,容易得到转移方程dp[i][1] = dp[i - 1][0] + val[i]
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1])
因位置i只与i-1有关,可用四个变量进行转移
class Solution {
public int deleteAndEarn(int[] nums) {
int[] val = new int[20005];
// int[][] dp = new int[10005][2];
int ma = 1, mi = 10000;
for (int i = 0; i < nums.length; i++) {
val[nums[i]]++;
ma = Math.max(ma, nums[i]);
mi = Math.min(mi, nums[i]);
}
for (int i = mi; i <= ma; i++) {
val[i] *= i;
}
int pre0 = 0, pre1 = 0, cur0 = 0, cur1 = 0;
for (int i = mi; i <= ma; i++) {
cur1 = pre0 + val[i];
cur0 = Math.max(pre0, pre1);
pre1 = cur1;
pre0 = cur0;
// dp[i][1] = dp[i - 1][0] + val[i];
// dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]);
}
// return Math.max(dp[ma][0], dp[ma][1]);
return Math.max(cur0, cur1);
}
}