#740 Delete and Earn

这篇博客介绍了如何使用动态规划解决一个数组操作问题:从给定的整数数组中选择元素并删除以赚取点数,但删除一个元素后必须删除其相邻的值。文章通过例子解释了问题的解决过程,并提供了Java代码实现。关键在于理解不能同时赚取数值上相邻的两个数,然后应用动态规划策略来最大化得分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

You are given an integer array nums. You want to maximize the number of points you get by performing the following operation any number of times:

  • Pick any nums[i] and delete it to earn nums[i] points.

Afterwards, you must delete every element equal to nums[i] - 1 and every element equal to nums[i] + 1.
Return the maximum number of points you can earn by applying the above operation some number of times.

Examples

Example 1:

Input: nums = [3,4,2]
Output: 6
Explanation: You can perform the following operations:

  • Delete 4 to earn 4 points. Consequently, 3 is also deleted. nums = [2].
  • Delete 2 to earn 2 points. nums = [].
    You earn a total of 6 points.

Example 2:
Input: nums = [2,2,3,3,3,4]
Output: 9
Explanation: You can perform the following operations:

  • Delete a 3 to earn 3 points. All 2’s and 4’s are also deleted. nums = [3,3].
  • Delete a 3 again to earn 3 points. nums = [3].
  • Delete a 3 once more to earn 3 points. nums = [].
    You earn a total of 9 points.

Constraints:
1 <= nums.length <= 2 * 104
1 <= nums[i] <= 104

思路

这里有一个容易被忽视的点是,他并不是不能同时earn位置上相邻的两个数,而是不能同时earn数值上相邻的两个数
在知道了这点之后,其实就是一个简单的动态规划。

代码

class Solution {
    public int deleteAndEarn(int[] nums) {
        Arrays.sort(nums);
        int i = 0;
        int pre = Integer.MIN_VALUE;
        
        int[] answer = new int[nums.length];
        answer[0] = 0;
        int temp = nums[0];
        while(i < nums.length && nums[i] == temp){
            answer[0] += nums[i];
            i++;
        }
        if(i == nums.length)
            return answer[0];
        pre = nums[0];
        
        answer[1] = 0;
        temp = nums[i];
        while(i < nums.length && nums[i] == temp){
            answer[1] += nums[i];
            i++;
        }
        if(i == nums.length){
            if(nums[i - 1] == pre + 1)
                return Math.max(answer[0], answer[1]);
            else
                return answer[0] + answer[1];
        }
        if(nums[i - 1] == pre + 1)
            answer[1] = Math.max(answer[0], answer[1]);
        else
            answer[1] = answer[0] + answer[1];
        pre = nums[i - 1];   
        
        int step = 2;
        while(i < nums.length){
            int sum = 0;
            temp = nums[i];
            while(i < nums.length && nums[i] == temp){
                sum += nums[i];
                i++;
            }
            
            if(nums[i - 1] == pre + 1)
                answer[step] = Math.max(answer[step - 2] + sum, answer[step - 1]);
            else
                answer[step] = Math.max(answer[step - 2], answer[step - 1]) + sum;
            step++;
            pre = nums[i - 1];
        }
        
        return Math.max(answer[step - 1], answer[step - 2]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值