题目链接
题目大意
给你一个整数数组
n
u
m
s
nums
nums ,你可以对它进行一些操作。
每次操作中,选择任意一个 n u m s [ i ] nums[i] nums[i],删除它并获得 n u m s [ i ] nums[i] nums[i] 的点数。之后,你必须删除 所有 等于 n u m s [ i ] nums[i] nums[i] - 1 和 n u m s [ i ] nums[i] nums[i] + 1 的元素。
开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数。
示例 1
输入:nums = [3,4,2]
输出:6
解释:删除 4 获得 4 个点数,因此 3 也被删除。之后,删除 2 获得 2 个点数。
总共获得 6 个点数。
示例 2
输入:nums = [2,2,3,3,3,4]
输出:9
解释:删除 3 获得 3 个点数,接着要删除两个 2 和 4 。之后,再次删除 3
获得 3 个点数,再次删除 3 获得 3 个点数。总共获得 9 个点数。
提示:
1
≤
n
u
m
s
.
l
e
n
g
t
h
≤
2
∗
1
0
4
1 \leq nums.length \leq 2 * 10^4
1≤nums.length≤2∗104
1
≤
n
u
m
s
[
i
]
≤
1
0
4
1 \leq nums[i] \leq 10^4
1≤nums[i]≤104
动态规划
1.确定状态:
f
[
i
]
[
0
]
f[i][0]
f[i][0]: 表示 1 ~
i
i
i 中不选
i
i
i 的所有选择状态的集合。
f
[
i
]
[
1
]
f[i][1]
f[i][1]:表示 1 ~
i
i
i 中选
i
i
i 的所有选择状态的集合。
2.状态转移
当前
i
i
i 这个状态只有选 或 是不选两种情况,如果选
i
i
i,那么第
i
i
i - 1 那个状态不能选,即
f
[
i
]
[
1
]
f[i][1]
f[i][1] =
f
[
i
−
1
]
[
0
]
f[i-1][0]
f[i−1][0] +
v
a
l
[
i
]
val[i]
val[i]。如果不选
i
i
i,那么第
i
i
i - 1 个状态可以选,在前
i
i
i - 1 的状态集合中选最大值即可,即
f
[
i
]
[
0
]
f[i][0]
f[i][0] =
m
a
x
max
max(
f
[
i
−
1
]
[
0
]
f[i-1][0]
f[i−1][0],
f
[
i
−
1
]
[
1
]
f[i-1][1]
f[i−1][1])。
class Solution {
public:
int deleteAndEarn(vector<int>& nums) {
int n = nums.size(), maxx = -1;
for(int i = 0; i < n; i++)
if(nums[i] > maxx) maxx = nums[i];
vector<int>val(maxx+1,0);
for(int i = 0; i < n; i++) val[nums[i]] += nums[i];
int dp[maxx+1][2];
memset(dp,0,sizeof dp);
for(int i = 1; i <= maxx; i++)
{
dp[i][0] = max(dp[i-1][0],dp[i-1][1]);
dp[i][1] = dp[i-1][0] + val[i];
}
return max(dp[maxx][1],dp[maxx][0]);
}
};