给你一个整数数组 nums ,你可以对它进行一些操作。
每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除 所有 等于 nums[i] - 1 和 nums[i] + 1 的元素。
开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数。
来源:力扣(LeetCode)
动态规划
由题可知:当你选了一个数 x ,那么 x - 1 和 x + 1, 则不做选择
例如 ;nums = [1, 1, 2, 2, 2, 3, 3, 3, 3, 4]
当你选择 1 时, 0 和 2去除,我们发现,数据是一组一组的去除的,所以我们不妨申请一个新的数组 book 来记录每个数据出现的次数
例如 本例中 所匹配的 book = [0, 2, 3, 4, 1]
即 0 出现了 0 次, 1 出现了 2次, 2 出现了 3次 ......
可以联想到198. 打家劫舍 对 book 数组应用
状态方程为 dp[i] = max {dp[i - 2] + book[i] * i, dp[i - 1]}
int
deleteAndEarn(int* nums, int numsSize)
{
int max = 0;
for (int i = 0; i < numsSize; i ++)
{
max = fmax (max, nums[i]);
}
int sum[max + 1];
memset (sum, 0, sizeof (sum));
for (int j = 0; j < numsSize ; j ++)
{
sum[nums[j]] ++;
}
int *dp = (int *)malloc (sizeof (int) * (max + 1));
dp[0] = sum[0] * 0;
dp[1] = sum[1] * 1;
for (int k = 2; k < max + 1; k ++)
{
dp[k] = fmax (dp[k - 2] + sum[k] * k, dp[k - 1]);
}
return dp[max];
}