【Leetcode】740. Delete and Earn

题目地址:

https://leetcode.com/problems/delete-and-earn/description/

给定一个长 n n n数组 A A A,可以从中依次挑选若干数,如果挑了 x x x,那么所有的 x − 1 , x + 1 x-1,x+1 x1,x+1就都不允许挑了。问挑的数总和最大值。题目保证 A A A中只有正整数。

f [ i ] [ 0 , 1 ] f[i][0,1] f[i][0,1]分别为只考虑 A A A 1 ∼ i 1\sim i 1i的数情况下,不取 i i i和取 i i i各自情况下能取得的数总和的最大值。由于 A A A中只有正整数,那么某个数要么不取,如果取则肯定要全取。如果 i i i这个数不取的话,那么 i − 1 i-1 i1这个数可以取也可以不取,从而 f [ i ] [ 0 ] = max ⁡ { f [ i − 1 ] [ 0 ] , f [ i − 1 ] [ 1 ] } f[i][0]=\max\{f[i-1][0],f[i-1][1]\} f[i][0]=max{f[i1][0],f[i1][1]};如果 i i i这个数取的话,那么 i − 1 i-1 i1必然不能取,从而 f [ i ] [ 1 ] = i × c [ i ] + f [ i − 1 ] [ 0 ] f[i][1]=i\times c[i]+f[i-1][0] f[i][1]=i×c[i]+f[i1][0] c [ i ] c[i] c[i]表示 i i i A A A中出现的次数。代码如下:

class Solution {
 public:
  int deleteAndEarn(vector<int>& nums) {
    int M = *max_element(nums.begin(), nums.end());
    int cnt[M + 1];
    memset(cnt, 0, sizeof cnt);
    for (int x : nums) cnt[x]++;
    int f[M + 1][2];
    memset(f, 0, sizeof f);
    int res = 0;
    for (int i = 1; i <= M; i++) {
      f[i][0] = max(f[i - 1][0], f[i - 1][1]);
      f[i][1] = f[i - 1][0] + i * cnt[i];
      res = max({res, f[i][0], f[i][1]});
    }

    return res;
  }
};

时空复杂度 O ( max ⁡ A ) O(\max A) O(maxA)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值