选中一个数,要将前一个数和后一个数完全删除,因此我们可以排序后,按顺序来删除。此时由于删除只与实际数值有关,与index无关,那么这里有个技巧就是状态表示的时候令
f[i][1] 表示选择数值为i的数获得得最大点数。
f[i][0]表示不选数值为i的数获得的最大点数。
由于数可能会有重复,当选一次的时候,就要删除所有前一个和后一个,对当前这一位没有影响,因此我们全部都选上。所以用cnt数组记录每个数出现的个数,这样对于没有出现的数,就用0处理,不影响结果。
const int N = 10010;
int f[N][2];
int cnt[N];
class Solution {
public:
int deleteAndEarn(vector<int>& nums) {
memset(f, 0, sizeof(f));
memset(cnt, 0, sizeof(cnt));
int res = 0;
for(auto num : nums){
cnt[num]++;
}
for(int i = 1; i < N; i++){
// 不选第i个数
f[i][0] = max(f[i - 1][1], f[i - 1][0]);
// 选第i个数
f[i][1] = f[i - 1][0] + i * cnt[i];
res = max(f[i][0], f[i][1]);
}
return res;
}
};