当前位置: 首页 > news >正文

每日OJ题_01背包③_力扣494. 目标和(dp+滚动数组优化)

目录

力扣494. 目标和

问题解析

解析代码

滚动数组优化代码


力扣494. 目标和

494. 目标和

难度 中等

给你一个非负整数数组 nums 和一个整数 target 。

向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :

  • 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。

返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

示例 1:

输入:nums = [1,1,1,1,1], target = 3
输出:5
解释:一共有 5 种方法让最终目标和为 3 。
-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3

示例 2:

输入:nums = [1], target = 1
输出:1

提示:

  • 1 <= nums.length <= 20
  • 0 <= nums[i] <= 1000
  • 0 <= sum(nums[i]) <= 1000
  • -1000 <= target <= 1000
class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {}
};

问题解析

        本题可以直接用暴搜的方法解决。但是稍微用数学知识分析⼀下,就能转化成常见的背包模型问题。

        设我们最终选取的结果中,前面加 + 号的数字之和为 a ,前面加 - 号的数字之和为 b ,整个数组的总和为 sum ,于是有:

  • a + b = sum
  • a - b = target

        上面两个式子消去 b 之后,可以得到 a = (sum + target) / 2 ,也就是说,我们仅需在 nums 数组中选择一些数,将它们凑成和为 (sum + target) / 2 即可。问题就变成了力扣416. 分割等和子集这道题。 可以用相同的分析模式,来处理这道题。


以某个位置为结尾,结合题目要求,定义一个状态表示:

dp[i][j] 表示:在前 i 个数中选,总和正好等于 j ,一共有多少种选法。

状态转移方程:

dp 状态转移方程分析方式,一般都是根据最后一步的状况,来分情况讨论:

  • 不选择 nums[i] :那么我们凑成总和 j 的总方案,就要看在前 i - 1 个元素中选,凑成总和为 j 的方案数。根据状态表示,此时 dp[i][j] = dp[i - 1][j] ; 。
  • 选择 nums[i] :这种情况下是有前提条件的,此时的 j 应该是大于等于 nums[i]。 因为如果这个元素都比要凑成的总和大,那选择它就没有意义。那么能够凑成总和为 j 的方案数,就要看在前 i - 1 个元素中选,能否凑成总和为 j - nums[i] 。根据 状态表示,此时 dp[i][j] = dp[i - 1][j - nums[i]] ; (j >= nums[i] )。

        综上,两种情况如果存在的话,应该要累加在⼀起。因此,状态转移方程为: if(j >= nums[i - 1]) dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i]] ; else dp[i][j] = dp[i - 1][j] ;(如果多加一行一列,找原数组下标要减1)


初始化:多加一行一列,方便初始化,由于需要用到上一行的数据,因此可以先把第一行初始化。 第一行表示不选择任何元素,要凑成目标和 j 。只有当目标和为 0 的时候才能做到,因此第一行仅需初始化第一个元素 dp[0][0] = 1。

填表顺序:根据状态转移方程,需要从上往下填写每一行,每一个的顺序是任意的。

返回值:根据状态表示,返回 dp[n][a] 的值。 其中 n 表示数组的大小, target 表示要凑成的目标和。


解析代码

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum = 0, n = nums.size();;for(auto& e : nums){sum += e;}int a = (sum + target) / 2;if(a < 0 || (sum + target) % 2) // 小于0或者除不尽return 0;vector<vector<int>> dp(n + 1, vector<int>(a + 1, 0));dp[0][0] = 1;for(int i = 1; i <= n; ++i){for(int j = 0; j <= a; ++j) // 第1列用到dp[0][0]初始化{if(j >= nums[i - 1])dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i - 1]];elsedp[i][j] = dp[i - 1][j];}}return dp[n][a];}
};

滚动数组优化代码

背包问题基本上都是利用滚动数组来做空间上的优化:(时间也有常数的优化)

  1. 利用滚动数组优化。
  2. 直接在原始代码上修改。

在01背包问题中,优化的结果为:

  1. 删掉所有的横坐标。
  2. 修改一下 j 的遍历顺序。

(滚动数组优化代码只需能在原代码上修改就行,不用考虑什么状态表示)

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum = 0, n = nums.size();;for(auto& e : nums){sum += e;}int a = (sum + target) / 2;if(a < 0 || (sum + target) % 2) // 小于0或者除不尽return 0;vector<int> dp(a + 1, 0);dp[0] = 1;for(int i = 1; i <= n; ++i){for(int j = a; j >= nums[i - 1]; --j) // 滚动数组优化{dp[j] += dp[j - nums[i - 1]];}}return dp[a];}
};

相关文章:

每日OJ题_01背包③_力扣494. 目标和(dp+滚动数组优化)

目录 力扣494. 目标和 问题解析 解析代码 滚动数组优化代码 力扣494. 目标和 494. 目标和 难度 中等 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 或 - &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式 &#xff1a; …...

vue3+element plus图片预览点击按钮直接显示图片的预览形式

1 需求 直接上需求&#xff1a; 我想要直接点击下面这个“预览”按钮&#xff0c;然后呈现出预览图片的形式 ok&#xff0c;需求知道了&#xff0c;下面让我们来看看如何实现吧 ~ 2 实现 template部分 <el-buttontype"primary"size"small"click&qu…...

GAMS104 现代游戏引擎 2

渲染的难点可以分为一下三部分&#xff1a;如何计算入射光线、如何考虑材质以及如何实现全局光照。 渲染的难点之一在于阴影&#xff0c;或者说是光的可见性。如何做出合适的阴影效果远比想象中要难得多&#xff0c;在实践中往往需要通过大量的技巧才能实现符合人认知的阴影效…...

spring boot学习第十七篇:OAuth2概述及使用GitHub登录第三方网站

0. 导言 我们在浏览器上可以访问成百上千个网站&#xff0c;使用每个网站的服务一般都要先注册账号&#xff0c;那么我们为了更好地记忆&#xff0c;一般都会在多个网站使用相同的账号和密码进行注册。那么问题就来了&#xff0c;如果在你注册的网站中有某些个网站的系统设计不…...

基于springboot的电影评论网站系统源码数据库

基于springboot的电影评论网站系统源码数据库 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了电影评论网站的开发全过程。通过分析电影评论网站管理的不足&#xff0c;创建了一个计算机管理电影评论网站的方案。文…...

javaScript手写专题——实现instanceof/call/apply/bind/new的过程/继承方式

目录 原型链相关 手写instanceof 实现一个_instance方法&#xff0c;判断对象obj是否是target的实例 测试 手写new的过程 实现一个myNew方法&#xff0c;接收一个构造函数以及构造函数的参数&#xff0c;返回构造函数创建的实例对象 测试myNew方法 手写类的继承 ES6&…...

C++11 新特性:tuple 元组

std::tuple是 C11 中引入的一个非常强大的类型&#xff0c;它允许将多个类型不同的值&#xff0c;组合成单一对象。 std::tuple非常适合用于那些需要返回多个值的场景&#xff0c;而且它的灵活性和通用性使得其成为现代 C 编程中不可或缺的一部分。下面&#xff0c;我们将探讨…...

最齐全,最简单的免费SSL证书获取方法——实现HTTPS访问

一&#xff1a;阿里云 优势&#xff1a;大平台&#xff0c;在站长中知名度最高&#xff0c;提供20张免费单域名SSL证书 缺点&#xff1a;数量有限&#xff0c;并且只有单域名证书&#xff0c;通配符以及多域名没有免费版本。并且提供的单域名证书只有三个月的期限。 二&#…...

c语言->贪吃蛇实战技巧结合EasyX简单实现页面管理(简单实现)

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;再无B&#xff5e;U&#xff5e;G-CSDN博客 1. 游戏背景 贪吃蛇是久负盛名的游戏&#xff0c;它也和俄罗斯⽅…...

C语言-详解内存函数

文章目录 1.memcpy使用和模拟实现1.1 memcpy函数的使用规则1.2 memcpy函数的使用1.2 模拟实现memcpy函数 2.memmove 函数的使用和模拟实现2.1 memmove 函数使用规则2.2 memmove函数的使用2.3 模拟实现memmove函数2.3.1 从后往前移2.3.2 从前往后移 2.4 算法实现2.4.1 从前往后移…...

【核心完整复现】基于目标级联法的微网群多主体分布式优化调度

1 主要内容 之前发布了华电学报的复现程序《基于目标级联法的微网群多主体分布式优化调度》&#xff0c;具体链接为【防骗版】基于目标级联法的微网群多主体分布式优化调度&#xff0c;虽然对模型及结果进行了复现&#xff0c;但是部分模型细节和参数并没有完全实现&#xff0…...

Mac下安装NVM,NVM安装Node(附带NPM)

1、理解NVM、node、NPM 什么是NVM&#xff1f; NVM: Node.js Version Manager&#xff0c;用来管理 node 的版本。 什么是 Node.js? Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js使用了一个事件驱动、非阻塞式I/O的模型&#xff08; Node.js的特性&…...

java之变量的作用域

在java中&#xff0c;变量需要像其他编程语言中先定义&#xff0c;再使用。但并不是定义好就能用。需要对变量定义一个作用范围才能使用&#xff0c;这个作用范围称为作用域。 在java程序中&#xff0c;变量会定义在一个花括号内&#xff0c;花括号内的区域就是作用域。 比如…...

CentOS 7软件安装全攻略:YUM命令详解与实战

在CentOS 7中&#xff0c;软件安装主要依赖于其强大的包管理器——YUM&#xff08;Yellowdog Updater Modified&#xff09;。YUM可以自动解决软件包之间的依赖关系&#xff0c;使得软件的安装、更新和卸载变得简单而高效。本文将详细介绍CentOS 7中软件安装的相关命令、选项和…...

达梦关键字(如:XML,EXCHANGE,DOMAIN,link等)配置忽略

背景&#xff1a;在使用达梦数据库时&#xff0c;查询SQL中涉及XML,EXCHANGE,DOMAIN,link字段&#xff0c;在达梦中是关键字&#xff0c;SQL报关键词不能使用的错误。 解决办法&#xff1a; 配置达梦安装文件E:\MyJava\dmdbms\data\DAMENG\dm.ini 忽略这些关键词&#xff0c;…...

2024/4/11 直流电机调速/PWM

一、直流电机简介和PWM原理 直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极&#xff0c;当电极正接时&#xff0c;电机正转&#xff0c;当电极反接时&#xff0c;电机反转 直流电机主要由永磁体&#xff08;定子&#xff09;、线圈&#xff08;转子&…...

贝乐虎儿歌v6.8.0解锁高级版亲子学习儿歌

软件介绍 贝乐虎儿歌免费版app&#xff0c;出自乐擎网络的创意工坊&#xff0c;专为孩子们雕琢了一系列富含创意的动画儿歌内容。这款app通过贝乐虎兄弟的可爱形象&#xff0c;让孩子们在愉快的观看中接触到各种儿歌和故事。不仅如此&#xff0c;app还巧妙地将古诗、英语等学习…...

计算机网络技术-RIP、0SPF和BGP协议的工作原理和应用

目录 RIP (Routing Information Protocolv&#xff09;路由信息协议OSPF(Open Shortest Path First) 开放式最短路径优先BGP( Border Gateway Protocol)边界网关协议 RIP (Routing Information Protocolv&#xff09;路由信息协议 RIP协议 是 TCP/IP环境中开发的第一个路由选择…...

机器学习——自动驾驶

本章我们主要学习以下内容: 阅读自动驾驶论文采集数据根据论文搭建自动驾驶神经网络训练模型在仿真环境中进行自动驾驶 论文介绍 本文参考自2016年英伟达发表的论文《End to End Learning for Self-Driving Cars》 📎end2end.pdf...

Android 14 vold 分析(2)VolumeManager 和 NetlinkManger

3. VolumeManager::Instance() 和 VolumeManager::start() system/vold/VolumeManager.cpp 3.1 Instance()没啥好说的 非常简单 112 VolumeManager* VolumeManager::Instance() {113 if (!sInstance) sInstance new VolumeManager();114 return sInst…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...