LeetCode 740 Delete and Earn (dp)

244 篇文章 0 订阅
177 篇文章 0 订阅

Given an array nums of integers, you can perform operations on the array.

In each operation, you pick any nums[i] and delete it to earn nums[i] points. After, you must delete everyelement equal to nums[i] - 1 or nums[i] + 1.

You start with 0 points. Return the maximum number of points you can earn by applying such operations.

Example 1:

Input: nums = [3, 4, 2]
Output: 6
Explanation: 
Delete 4 to earn 4 points, consequently 3 is also deleted.
Then, delete 2 to earn 2 points. 6 total points are earned.

Example 2:

Input: nums = [2, 2, 3, 3, 3, 4]
Output: 9
Explanation: 
Delete 3 to earn 3 points, deleting both 2's and the 4.
Then, delete 3 again to earn 3 points, and 3 again to earn 3 points.
9 total points are earned.

Note:

  • The length of nums is at most 20000.
  • Each element nums[i] is an integer in the range [1, 10000].

题目大意:https://leetcode.com/problems/delete-and-earn/

题目分析:若取某个数字,必然会全取,设val[i]为数字i的总和,设dp[i][0/1]表示到数字i,不取/取时的最大值,容易得到转移方程dp[i][1] = dp[i - 1][0] + val[i]
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1])

因位置i只与i-1有关,可用四个变量进行转移

class Solution {
    
    public int deleteAndEarn(int[] nums) {
        int[] val = new int[20005];
        // int[][] dp = new int[10005][2];
        int ma = 1, mi = 10000;
        for (int i = 0; i < nums.length; i++) {
            val[nums[i]]++;
            ma = Math.max(ma, nums[i]);
            mi = Math.min(mi, nums[i]);
        }
        for (int i = mi; i <= ma; i++) {
            val[i] *= i;
        }
        int pre0 = 0, pre1 = 0, cur0 = 0, cur1 = 0;
        for (int i = mi; i <= ma; i++) {
            cur1 = pre0 + val[i];
            cur0 = Math.max(pre0, pre1);
            pre1 = cur1;
            pre0 = cur0;
            // dp[i][1] = dp[i - 1][0] + val[i];
            // dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]);
        }
        // return Math.max(dp[ma][0], dp[ma][1]);
        return Math.max(cur0, cur1);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值