首页 > 其他分享 >【DP】LeetCode 740. 删除并获得点数

【DP】LeetCode 740. 删除并获得点数

时间:2023-04-26 14:58:46浏览次数:60  
标签:740 状态 nums int sum num DP LeetCode dp

题目链接

740. 删除并获得点数

思路

分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律

在数组的动态规划问题中,一般 dp[i] 都是表示以 nums 以前 i 个元素组成(即 nums[i - 1])的状态;dp[i][j] 分别表示以 nums1 前 i 个元素(即 nums1[i - 1])组成和以 nums2 前 j 个元素(即 nums2[j - 1])组成的状态,以此类推

字符串也是个数组,是字符数组

表示状态

状态表示就是靠猜,但是会有猜的套路,一般都是通过最终结果和数组数量来猜

先上结论:\(dp[i]\) 表示到数字 i 为止能获得的最大点数。

这个题的状态表示很有意思,大部分的状态表示是到 \(nums\) 前 i 个数为止的状态,即让 \(nums\) 的下标作为存取状态的索引,但这个题是让 \(nums\) 的值作为存取状态的索引,还是比较难想到的。

找状态转移方程

思考的方向是:大问题的最优解怎么由小问题的最优解得到

当遍历到数字 i 的时候,只有两种情况需要考虑:

  1. 不选择数字 i
  2. 选择数字 i,舍弃数字 i - 1

在这两种情况下取最大值,便是我们的最优子结构

\[dp[i] = \max(dp[i - 1], dp[i - 2] + 数字 i 的总和) \]

为了方便求每个数字的总和,我们建立哈希表 \(sum[i]\) 表示数字 i 在 \(nums\) 中的总和,所以状态转移方程最终如下所示

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

边界处理

\[dp[1] = sum[1] \]

空间优化

因为 \(dp[i]\) 只和 \(dp[i - 2]\) 还有 \(dp[i - 1]\) 有关,可以替换为三个变量循环滚动更新。

代码

dp数组版

class Solution {
    public int deleteAndEarn(int[] nums) {
        // 打表存储每个元素的总和
        int[] sum = new int[10001];
        for (int num : nums) {
            sum[num] += num;
        }

        // dp[i] 表示到数字 i 能取得的分数最大值
        int[] dp = new int[10001];
        int result = 0;
        dp[1] = sum[1];
        for (int i = 2; i <= 10000; i++) {
            // 分为两种情况
            // 1.不选择数字 i
            // 2.选择数字 i,舍弃数字 i - 1
            dp[i] = Math.max(dp[i - 1], dp[i - 2] + sum[i]);
            result = Math.max(result, dp[i]);
        }

        return result;
    }
}

空间优化版

class Solution {
    public int deleteAndEarn(int[] nums) {
        // 打表存储每个元素的总和
        int[] sum = new int[10001];
        for (int num : nums) {
            sum[num] += num;
        }

        int prevMax = 0;
        int currMax = 0;
        for (int i = 1; i <= 10000; i++) {
            int temp = currMax;
            // 分为两种情况
            // 1.不选择数字 i
            // 2.选择数字 i,舍弃数字 i - 1
            currMax = Math.max(currMax, prevMax + sum[i]);
            prevMax = temp;
        }

        return currMax;
    }
}

标签:740,状态,nums,int,sum,num,DP,LeetCode,dp
From: https://www.cnblogs.com/shixuanliu/p/17356047.html

相关文章

  • LeetCode 152. 乘积最大子数组
    20230426顺利通过原题解题目约束题解classSolution{public:intmaxProduct(vector<int>&nums){intmaxF=nums[0],minF=nums[0],ans=nums[0];for(inti=1;i<nums.size();++i){intmx=maxF,mn=minF;......
  • C# 获取系统DPI缩放比例以及分辨率大小
    一般方法System.Windows.Forms.Screen类//获取当前主屏幕分辨率intscreenWidth=Screen.PrimaryScreen.Bounds.Width;intscreenHeight=Screen.PrimaryScreen.Bounds.Height;//获取指定屏幕分辨率ScreensecondaryScreen=Screen.AllScreens[1];intsecondaryScree......
  • [LeetCode] 2418. Sort the People
    Youaregivenanarrayofstrings names,andanarray heights thatconsistsof distinct positiveintegers.Botharraysareoflength n.Foreachindex i, names[i] and heights[i] denotethenameandheightofthe ith person.Return names sorted......
  • 【LeetCode动态规划#13】买卖股票含冷冻期(状态众多,比较繁琐)、含手续费
    最佳买卖股票时机含冷冻期力扣题目链接(opensnewwindow)给定一个整数数组,其中第i个元素代表了第i天的股票价格。设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):你不能同时参与多笔交易(你必须在再次购买前出售掉之前......
  • 区间dp
    区间dp前情提要先赞后看,必成习惯一、区间dp-常见的也常考的dp1.区间dp是什么?区间动态规划是用dp的状态来表示和一段区间有关的性质,比如说dp[i][j]表示解决区间[i,j]上的子问题的最小代价或最大收益,然后利用区间子问题之间的关系递推求解。2.区间dp怎么写?区间dp常见的有......
  • LeetCode 1643. 第 K 条最小指令
    康托展开一开始无脑枚举全排列,果断超时,还是得看看如果降低计算量。题目destination=[2,3],相当于2个V,3个H,输出全排列去重后的对应位置字典序列内容。忽略去重则问题为全排列,所有可能为:\[(\sumdestination)!=(2+3)!=5!\]k恰好为康托展开结果+1,直接逆向......
  • leetcode调研version0
     这是我第一次发博客,所以许多功能还不太会使用。前几次的随笔既当作记录,也当作自己的练习。 最近想要刷leetcode,纠结用哪种语言(我自己学过c/c++,python,fortran,Java),所以前期做了一些调研,在此记录一下。 c语言: 网址:https://github.com/begeekmyfriend/leetcode ......
  • leetcode 607 銷售員
    銷售員 selects.`name`fromsalespersonsleftjoinordersoons.sales_id=o.sales_idleftjoincompanycono.com_id=c.com_idandc.name='RED'groupbys.sales_idhavingcount(c.`name`)=0 ===selects.`name`fromsalespersonswheres.sa......
  • LengthFieldPrepender和LengthFieldBasedFrameDecoder
    1,使用LengthFieldPrepender编码,LengthFieldBasedFrameDecoder解码的netty传输......
  • 【DP】LeetCode 213. 打家劫舍 II
    题目链接213.打家劫舍II思路分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律在数组的动态规划问题中,一般dp[i]都是表示以nums以前i个元素组成(即nums[i-1])的状态;dp[i][j]分别表示以nums1前i个元素(即n......