首页 > 其他分享 >动态规划:删除并获得点数

动态规划:删除并获得点数

时间:2024-08-03 09:53:44浏览次数:15  
标签:count 删除 nums max num 点数 动态 dp

目录

题目描述

思路

解题过程

复杂度

Code 


题目描述

        给你一个整数数组 nums ,你可以对它进行一些操作。每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除 所有 等于 nums[i] - 1 和 nums[i] + 1 的元素。开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数。

示例 1:

输入:nums = [3,4,2]
输出:6
解释:
删除 4 获得 4 个点数,因此 3 也被删除。
之后,删除 2 获得 2 个点数。总共获得 6 个点数。

示例 2:

输入:nums = [2,2,3,3,3,4]
输出:9
解释:
删除 3 获得 3 个点数,接着要删除两个 2 和 4 。
之后,再次删除 3 获得 3 个点数,再次删除 3 获得 3 个点数。
总共获得 9 个点数。

提示:

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

思路

动态规划


解题过程

1.统计每个数字的点数

  • 首先,使用一个哈希表 count 统计每个数字出现的次数,并计算每个数字对应的点数。

2.动态规划状态定义

  • 定义一个数组 dp,其中 dp[i] 表示在数字 i 处获得的最大点数总和。

3.状态转移方程

  • 对于每个数字 i,有两种选择:
    • 选择当前数字 i:此时可以获得点数 i * count[i],同时需要考虑前一个数字的最大点数,即 dp[i-2] + i * count[i]
    • 不选择当前数字 i:则当前的最大点数为 dp[i-1]
  • 综合考虑,状态转移方程为:dp[i] = max(dp[i-1], dp[i-2] + i * count[i])

4.边界条件

  • 数组中的数字范围在 [1, 10000],所以需要定义一个足够大的数组 dp,以覆盖这个范围。

5.实现

  • 首先,统计每个数字出现的次数并初始化 dp 数组。
  • 然后,根据上述状态转移方程计算 dp 数组的值。
  • 最终,dp[10000] 即为所求的最大点数。

复杂度

  • 时间复杂度:统计数字出现次数的操作是 O(n),动态规划的状态转移是 O(max_num),其中 max_num 是数组中的最大数字,因此总的时间复杂度是 O(n + max_num)

  • 空间复杂度:除了输入数组外,使用了一个大小为 max_num + 1 的数组 dp 和一个大小为 max_num + 1 的哈希表 count,因此空间复杂度是 O(max_num)


Code 

class Solution(object):
    def deleteAndEarn(self, nums):
        if not nums:
            return 0
    
        max_num = max(nums)
        count = [0] * (max_num + 1)
    
        for num in nums:
            count[num] += num
    
        dp = [0] * (max_num + 1)
        dp[1] = count[1]
    
        for num in range(2, max_num + 1):
            dp[num] = max(dp[num-1], dp[num-2] + count[num])
    
        return dp[max_num]

 

标签:count,删除,nums,max,num,点数,动态,dp
From: https://blog.csdn.net/Sxiaocai/article/details/140885917

相关文章

  • VUE动态路由和按钮的实现
    动态路由动态菜单//通过循环组件完成动态菜单<el-menuactive-text-color="#ffd04b"background-color="#545c64"class="el-menu-vertical-demo"text-color="#fff":collapse="isCollapse"routerdefault-activestyle="......
  • 动态规划学习笔记
    P3195求出玩具的前缀和\(S\)。设\(f_i\)表示区间\([1,i]\)的最大答案。开始应该是\(f_0=0\)。\(f_i=\max_{1\lej<i}f_j+(i+S_i-L-1-(j+S_j))^2\)。\(f_i=\max_{1\lej<i}f_j+(i+S_i-L-1)^2+(j+S_j)^2-2(i+S_i-L-1)(j+S_j)\)。设\(g_i=i+S_i,k=L+1\),那么\(f_......
  • Redis学习[5] ——Redis过期删除和内存淘汰
    六、Redis过期键值删除6.1Redis的过期键值删除策略6.1.1什么是过期键值删除?Redis中是可以对key设置过期时间的,所以需要有相应的机制将已过期的键值对删除,也就是**过期键值删除策略。Redis会用一个过期字典(expiresdict)**来存储有过期时间的所有key。当查询一个key时,Red......
  • Oracle中删除表中的重复数据
    确定重复数据:首先,你需要确定哪些记录是重复的。这通常涉及到一个或多个字段。选择保留的记录:决定在删除重复数据时保留哪个记录。这可以基于某个特定字段,例如保留具有最小或最大主键值的记录。删除重复记录:使用DELETE语句结合子查询来删除重复的记录。以下是一个示例,假设我们有......
  • 2024.7.26 动态规划专题赛
    省流:全是记忆化……T1想了\(30\min\),突然想出来了。设\(f[i][j]\)表示将第\(i\)个的前\(j\)个变成好串的最小代价。核心代码:f[i][j]=min(f[i-k][j-k]+f[i][k],f[i][j]);需要预处理,但是第一发T了。将预处理优化为:f[i][j]=f[i-2][j-4]+(s[l]==s[r]?0:min(w[l],w[......
  • Spring Boot 实现动态修改定时任务的执行时间
    SpringBoot实现动态修改定时任务的执行时间前提大家通过SpringBoot跑定时任务,用的最多的是@Scheduled,通过指定cron来定时的执行任务,cron可以使用SPEL表达式来通过配置文件配置,但是项目一旦启动,执行时间便无法修改,不够方便,本文基于此来优化项目启动之后不能动态修改cron的问题......
  • 动态语言、静态语言、强类型语言、弱类型语言的区别
    我们在学习编程语言的类型系统时,经常听说“静态语言”“动态语言”“强类型语言”和“弱类型语言”这些概念,它们究竟是什么意思呢?各个概念之间又有什么区别呢?如果你阅读互联网上的博客,你也可能会发现一些矛盾的观点,有的作者糊涂地认为静态语言=强类型语言,或者动态语言=弱类型......
  • antd react form.list动态增减表单项Switch受控
    importReact,{useState}from'react';import{Form,Input,Switch,Button}from'antd';constDemo=()=>{const[switches,setSwitches]=useState({});constonFinish=(values)=>{console.log('Received......
  • 如何在mysql中删除重复数据
    #分组去重法讲重复的列进行分组之后用min(id)#取其中最小的保留,其余的删除--步骤1:创建临时表,保存每组最小的IDCREATETEMPORARYTABLEtmp_keep_idsASSELECTMIN(id)ASidFROM重复表名GROUPBY重复列;--步骤2:删除原表中不在临时表中的记录DELETEFROM原表......
  • HarmonyOS:如何实现自定义的Tabs,TabContent内部实现如何动态配置
    前言:最近做开发任务的时候,想把Tabs自定义了,并且动态配置TabContent里面的内容,不是写死一样的,这个问题困扰了很长时间,试过**@BuilderParam**(类似于vue的插槽)传组件方式的,但是**@BuilderParam只能传一个,我想要传递的是一个数组,找了很多Api最后找到了WrappedBuilder[]**这种方......