740-删除并获得点数

题目

740. 删除并获得点数 - 力扣(LeetCode) (leetcode-cn.com)

思路

为了获取最多的点数,对于数组nums中的数字n,只存在所有的数字n均被记为点数(选择了数字n)和所有的数字n均没有被记为点数的情况(选择了数字n+1或者n-1使得所有n均被删除),即不存在只选择部分数字n的情况。

根据上述分析,本题目可以转化为从存在一些各不相同的数字,每个数字对应一个分数,当选择了数字n就不能选择数字n+1n-1,求所有可能选择方案得到的分数中的最大分数。

设最大的数字为n, 我们从n开始考虑, 如果我们选择该数字,则需要从所有数字中去掉n, n-1, n+1,由于n是最大的数字,因此仅需要去掉n,n-1,然后求剩余数字最大分数(问题规模减小);如果我们不选择,则需要从所有数字中去掉n,然后求剩余数字的最大分数(问题规模减小),最后再比较这两中选择,取分数较大的一个则得到最终结果。

根据上述分析,我们要求<=n的所有数字的最大分数(最终结果),可以利用<=n-1的数字的最大分数和<=n-2的数字的最大分数来求。我们使用数组dp[n]来表示<=n的所有数字的最大分数,则有

dp[n] = max(dp[n-1], dp[n-2] + sum[n])

显然dp[1] = sum[1], 由于某些数字在题目给出的数组中不存在,我们将这些数字对应的分数设置为0即可。从0迭代到n即可得到最终结果(数字从1开始,为了方便编程,可以将所有数字-1,使其从0开始)。

代码

class Solution {
public:
    int deleteAndEarn(vector<int>& nums) {
        int max_val =0;
        // 搜索最大的数字
        for(int i : nums) {
            if (i > max_val) {
                max_val = i;
            }
        }
        
        // 计算每种数字总点数和(vector自动初始化为0),
        // 因此原数组中不存在的数对应点数为0
        vector<int> sum(max_val);
        for(int i : nums) {
            // 将所有数字-1,方便存储
            sum[i-1] += i;
        }

        vector<int> dp(max_val);
        
        dp[0] = sum[0];
        for(int i=1; i<dp.size(); i++) {
            int max_a, max_b;
            // 选择当前数字
            max_a = sum[i];
            if (i > 1) {
                max_a += dp[i-2];
            }
            // 不选择当前数字
            max_b = dp[i-1];
            dp[i] = max(max_a, max_b);
        }
        return dp[max_val - 1];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值