【算法】动态规划 斐波那契类型: 740. 删除并获得点数

740. 删除并获得点数

中等

题目

给你一个整数数组 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


分析

这是一个非常经典的动态规划问题,跟「打家劫舍」非常相似

问题本质:

  • 如果你选了一个数 x,你会获得 x * 出现次数 的分数,并且不能再选 x-1x+1
  • 所以你不能同时选相邻的数(按照值排序)。
  • 相当于:把所有数按照值排序,把它们看成一排房子(每个房子有一定价值),不能取相邻的房子。

下面一步一步讲解和给出代码。


🟢 思路步骤

  1. 统计每个数字的总价值:

    • 用一个数组 sum[x] = x * 出现次数

    • 例如 nums = [2,2,3,3,3,4]

      • 2出现2次,贡献=2*2=4
      • 3出现3次,贡献=3*3=9
      • 4出现1次,贡献=4*1=4
  2. 动态规划:

    • 定义 dp[i]:考虑数字0~i,能取得的最大分数。

    • 转移方程:

      dp[i] = max(dp[i-1],            // 不取idp[i-2] + sum[i]    // 取i
      )
      
    • 为什么和打家劫舍一样?因为选了i就不能选i-1。

  3. 初始化:

    • dp[0] = sum[0]
    • dp[1] = max(sum[0], sum[1])
  4. 返回:

    • dp[max_value]max_value = max(nums)

🟢 Python代码

def deleteAndEarn(nums):if not nums:return 0max_num = max(nums)sum_points = [0] * (max_num + 1)# 统计每个数的总价值for num in nums:sum_points[num] += num# 动态规划dp = [0] * (max_num + 1)dp[0] = sum_points[0]dp[1] = max(sum_points[0], sum_points[1])for i in range(2, max_num + 1):dp[i] = max(dp[i - 1], dp[i - 2] + sum_points[i])return dp[max_num]

🟢 示例验证

示例1:

nums = [3,4,2]
sum_points: [0,0,2,3,4]
dp:
i=2: dp[2]=max(dp[1], dp[0]+sum[2]) = max(0,0+2)=2
i=3: dp[3]=max(dp[2], dp[1]+sum[3]) = max(2,0+3)=3
i=4: dp[4]=max(dp[3], dp[2]+sum[4]) = max(3,2+4)=6
输出:6

示例2:

nums = [2,2,3,3,3,4]
sum_points: [0,0,4,9,4]
dp:
i=2: dp[2]=max(dp[1], dp[0]+sum[2]) = max(0,0+4)=4
i=3: dp[3]=max(dp[2], dp[1]+sum[3]) = max(4,0+9)=9
i=4: dp[4]=max(dp[3], dp[2]+sum[4]) = max(9,4+4)=9
输出:9

✅完全符合题意。


c++


🟢 C++代码

#include <vector>
#include <algorithm>
using namespace std;class Solution {
public:int deleteAndEarn(vector<int>& nums) {if (nums.empty()) return 0;int maxNum = *max_element(nums.begin(), nums.end());// sum[i] = i * 出现次数vector<int> sum(maxNum + 1, 0);for (int num : nums) {sum[num] += num;}// dp[i] = 考虑[0..i]的最大点数vector<int> dp(maxNum + 1, 0);dp[0] = sum[0];dp[1] = max(sum[0], sum[1]);for (int i = 2; i <= maxNum; ++i) {dp[i] = max(dp[i - 1], dp[i - 2] + sum[i]);}return dp[maxNum];}
};

🟢 用法示例

你可以这样调用:

#include <iostream>int main() {Solution s;vector<int> nums = {2,2,3,3,3,4};cout << s.deleteAndEarn(nums) << endl;  // 输出 9return 0;
}

**空间优化(O(1)空间)**


非常好问题!

这个DP转移:

d p [ i ] = max ⁡ ( d p [ i − 1 ] , d p [ i − 2 ] + s u m [ i ] ) dp[i] = \max(dp[i-1], dp[i-2] + sum[i]) dp[i]=max(dp[i1],dp[i2]+sum[i])

只用到了 i-1i-2,所以不需要存整个数组,只需要两个变量即可。


🟢 O(1)空间优化思路

  • 维护两个变量:

    • prev1:表示 dp[i-1]
    • prev2:表示 dp[i-2]
  • 每次更新:

    curr = max(prev1, prev2 + sum[i]);
    

    然后:

    prev2 = prev1;
    prev1 = curr;
    

🟢 完整C++代码(O(1)空间)

#include <vector>
#include <algorithm>
using namespace std;class Solution {
public:int deleteAndEarn(vector<int>& nums) {if (nums.empty()) return 0;int maxNum = *max_element(nums.begin(), nums.end());vector<int> sum(maxNum + 1, 0);for (int num : nums) {sum[num] += num;}int prev2 = sum[0];                        // dp[i-2]int prev1 = max(sum[0], sum[1]);           // dp[i-1]int curr = prev1;for (int i = 2; i <= maxNum; ++i) {curr = max(prev1, prev2 + sum[i]);prev2 = prev1;prev1 = curr;}return curr;}
};

🟢 样例验证

如示例:

int main() {Solution s;vector<int> nums = {2,2,3,3,3,4};cout << s.deleteAndEarn(nums) << endl;  // 输出 9return 0;
}

✅ 输出正确。

这样就只用 O(1) 空间,时间复杂度依然是 O(N)。

如需要,我也可以帮你写 Java版本 或进一步优化逻辑!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/87154.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/87154.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AWS MySQL 读写分离配置指南

# AWS JDBC Wrapper读写分离配置实战&#xff1a;Spring Boot MyBatis Plus完整解决方案 ## 前言 在微服务架构中&#xff0c;数据库读写分离是提升系统性能的重要手段。本文将详细介绍如何在Spring Boot项目中使用AWS JDBC Wrapper实现自动读写分离&#xff0c;重点解决MyBat…

opencv检测运动物体

检测到的所有移动物体中轮廓中找到面积最大的轮廓&#xff0c;并绘制这个轮廓的矩形框。 #include <opencv2/opencv.hpp> #include <iostream>int main() {// 打开视频文件或摄像头cv::VideoCapture capture;capture.open("move3.mp4"); // 打开视频文件…

Camera相机人脸识别系列专题分析之十五:人脸特征检测FFD算法之libcvface_api.so算法API详细注释解析

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: Camera相机人脸识别系列专题分析之十五:人脸特征检测FFD算法之libcvface_api.so算法API详细注释解析 目录 一、libcvface_api.so算法API详细注释解析

图像擦除论文-2:SmartEraser、Erase Diffusion、OmniEraser

图像生成模型应用系列——图像擦除&#xff1a; 图像擦除论文-1&#xff1a;PixelHacker、PowerPanint等 图像擦除论文-2&#xff1a;擦除类型数据集构建(1) Erase Diffusion Erase Diffusion: Empowering Object Removal Through Calibrating Diffusion Pathways https://git…

九识无人车陕西运营中心展厅启幕 打造智能城配物流新标杆

7月1日&#xff0c;九识无人车陕西运营中心展厅正式开业&#xff0c;全国业务版图再添重要一子。这座展厅是九识在陕西省的首家展厅&#xff0c;由九识第一位正式提车的客户、首位代理商伙伴孙朋奇先生打造。展厅集产品展示与技术体验于一体&#xff0c;成为西北地区城配领域自…

AI智能体|扣子(Coze)搭建【沉浸式历史故事解说视频】工作流

主包讲解历史对我们的好处&#xff0c;纯个人观点&#xff01; 这个世界是存在一些规律的&#xff0c;很多东西并不能够通过自己的聪明去创新&#xff0c;去改变的。 无论你怎么样创新&#xff0c;你都会回到哪个规律中去&#xff0c;比如很多人做一些商业模式的创新&#xff0…

Softhub软件下载站实战开发(十):实现图片视频上传下载接口

文章目录 Softhub软件下载站实战开发&#xff08;十&#xff09;&#xff1a;实现图片视频上传下载接口 &#x1f5bc;️&#x1f3a5;系统架构图核心功能设计 &#x1f6e0;️1. 文件上传流程2. 关键技术实现2.1 雪花算法2.2 文件校验机制 ✅2.3 文件去重机制 &#x1f50d;2.…

[JS逆向] 喜马拉雅登录案例 -- 补环境

博客配套代码发布于github&#xff1a;喜马拉雅登录 &#xff08;欢迎顺手Star一下⭐&#xff09; 相关知识点&#xff1a;webpack 补环境 相关爬虫专栏&#xff1a;JS逆向爬虫实战 爬虫知识点合集 爬虫实战案例 逆向知识点合集 此案例目标为逆向成功对应的参数&#xff0c…

大语言模型推理系统综述

摘要 近年来&#xff0c;随着 ChatGPT 等服务推动大语言模型&#xff08;LLM&#xff09;的快速普及&#xff0c;一批专门面向 LLM 推理的系统相继涌现&#xff0c;如 vLLM、SGLang、Mooncake 和 DeepFlow。这些系统设计工作的核心动因是 LLM 请求处理过程中所特有的自回归特性…

用Firecrawl轻松获取网站数据,提升AI应用的效率!

&#x1f525; Firecrawl&#xff1a;助力AI应用的强大工具&#xff01; 在数字化信息爆炸的时代&#xff0c;如何高效地从海量网页中提取有用数据变得尤其重要。Firecrawl的问世&#xff0c;为我们揭开了一种便捷的方法来应对这一挑战。它不仅能够将整个网站的数据转化为适用…

【王阳明代数讲义】谷歌编程智能体Gemini CLI 使用指南、架构详解与核心框架分析

Gemini CLI 使用指南、架构详解与核心框架分析 Gemini CLI 使用指南、架构详解与核心框架分析Gemini CLI 使用指南Gemini CLI 架构详解Gemini CLI 核心框架总结 Gemini CLI 使用指南、架构详解与核心框架分析 Gemini CLI 使用指南 1. 安装与配置 环境要求&#xff1a; Node.…

camera调试:安卓添加xml注册

对接安卓的平台时&#xff0c;需要注册对应的camera设备&#xff0c;供安卓标准api进行操作&#xff0c;rk的平台需要在HAL层配置camera3_profiles.xml文件&#xff0c;适配驱动的信息&#xff0c;进行注册camera设备。该xml对应的内容很多&#xff0c;很多CTS测试问题都是该文…

使用 Ansys Discovery 为初学者准备几何结构

介绍 设计几何体通常会包含一些特征&#xff0c;使其无法直接导入我们的仿真工具&#xff0c;例如 Ansys Mechanical、LS-DYNA、Fluent 等。有些干扰或错位虽然适合制造&#xff0c;但在我们的仿真工具中却会造成问题。有时&#xff0c;一些小特征&#xff08;例如孔或圆角&am…

推客系统全栈开发指南:从架构设计到商业化落地

一、推客系统概述 推客系统&#xff08;TuiKe System&#xff09;是一种结合社交网络与内容分发的创新型平台&#xff0c;旨在通过用户间的相互推荐机制实现内容的高效传播。这类系统通常包含用户关系管理、内容发布、智能推荐、数据分析等核心模块&#xff0c;广泛应用于电商…

大数据开发实战:如何做企业级的数据服务产品

1.背景 数据服务通常以解决方案的形式进行组织&#xff0c;面向一个应用场景的所有数据需求或数据内容可以通过一个解决方案进行封装&#xff0c;统一对外服务。一个数据需求或数据接口以一个数据服务实例的形式存在于解决方案之下。 下游消费方可以通过统一API进行数据消费&…

基于IndexTTS的零样本语音合成

IndexTTS 项目采用模块化设计&#xff0c;将 BPE 文本编码、GPT 单元预测、dVAE 语音特征抽取和 BigVGAN 音频生成串联为完整的语音合成流程。系统通过统一的配置文件和模型目录规范&#xff0c;实现高效的文本到语音转换&#xff0c;支持命令行与 Web 界面双模式操作&#xff…

基于go-zero的短链生成系统

go-zero框架 gozero&#xff08;又称go-zero&#xff09;是一款由知名开发者kevwan设计的Golang微服务框架&#xff0c;专注于高性能、低延迟和易用性。其核心目标是简化分布式系统的开发&#xff0c;提供开箱即用的工具链&#xff0c;涵盖API网关、RPC服务、缓存管理、数据库…

Linux-修改线上MariaDB服务端口号

准备工作&#xff08;很重要&#xff01;&#xff01;&#xff01;&#xff09;&#xff1a; 提前做好Linux服务器快照 提前做好数据库数据备份 1. 修改配置文件 首先&#xff0c;我们需要找到MariaDB的配置文件。通常情况下&#xff0c;这个文件位于以下位置&#xff1a;…

Spring Cloud 微服务(负载均衡策略深度解析)

&#x1f4cc; 摘要 在微服务架构中&#xff0c;负载均衡是实现高可用、高性能服务调用的关键机制之一。Spring Cloud 提供了基于客户端的负载均衡组件 Ribbon&#xff0c;结合 Feign 和 OpenFeign&#xff0c;实现了服务间的智能路由与流量分配。 本文将深入讲解 Spring Clo…

HTML/CSS基础

1.html:超文本标记语言。它是一种标识性的语言&#xff0c;非编程语言&#xff0c;不能使用逻辑运算。通过标签将网络上的文本格式进行统一&#xff0c;使用分散网络资源链接为一个逻辑整体&#xff0c;属于标记语言。 超文本&#xff1a;就是指页面内可以包含图片&#xff0…