2021-11-01 leetcode 动态规划 740.删除并获取点数 c++

请添加图片描述
题目解释
选定nums数组中一个元素nums[i] = x。
删除nums[i]以及所有等于 x-1或 x+1 的元素。然后,再继续对其他元素进行相同操作。

思路
1: 若选择了 x,所有等于 x 的元素也应一同被选择
解释:在选定x之后,删除值为x和所有值为x+1、x-1的元素。此时,若还有多个值为 x的元素,由于所有等于 x-1或 x+1 的元素已经被删除,我们可以直接删除全部 x 并获得其点数。因此,若选择了 x,所有等于 x 的元素也应一同被选择,以尽可能多地获得点数。

2:用sum[x]将相同元素分别装起来,(cnt 记录每个数重复次数)sum[x]=x*cnt[x],最后在sum上进行操作。
解释:sum[x]为所有x的和,选定x后,则删除x+1和x-1,即不能获取sum[x+1]和sum[x-1]的点数。

综合1,2:问题转化为:对于sum数组,选择其中的元素,如sum[i],删除sum[I]并获取点数,但不能获取sum[I]左右两个元素的点数,即不能获取sum[I+1]和sum[I-1]的点数。现求可得最大点数。和198.打家劫舍思路相同。

动态规划问题关键是求状态转移方程

用dp[i][2]来表示得到的最大点数
dp[i][0]: 第i个元素未进行删除的状态下累积之前的最大点数
dp[i][1]: 第i个元素删除的状态下(删除第i个元素则意味着不删除第i-1个元素)累积之前的最大点数

可得状态转移方程如下
(1)dp[i][0] = max(dp[i-1][0], dp[i-1][1])
(2)dp[i][1] = dp[i-1][0] + nums[i]

AC代码

class Solution {
public:
    int deleteAndEarn(vector<int>& nums) {
        //preparation for sum
        int maxValue = 0;
        // int cnt[l];
        // int sum[l];
        // memset(cnt, 0, sizeof(cnt));
        // memset(sum, 0, sizeof(sum));
        vector<int> sum(10001,0);
        for(int val : nums) {
            sum[val] += val;
            maxValue = max(maxValue, val);
        }
        //operation to sum
        int dp[maxValue+1][2];
        dp[0][0] = 0;
        dp[0][1] = sum[0];
        for(int i = 1; i <= maxValue; i++) {
            dp[i][0] = max(dp[i-1][0], dp[i-1][1]);
            dp[i][1] = dp[i-1][0] + sum[i];
        }
        return dp[maxValue][0] > dp[maxValue][1] ? dp[maxValue][0] : dp[maxValue][1];
    }
};

//答案一直不对,以为是中间的问题,换其他方法来做,没想到是返回值出错了!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

聪明的Levi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值