leetCode 2915. 和为目标值的最长子序列的长度 + 动态规划 +01背包 + 空间优化 + 记忆化搜索 + 递推

2915. 和为目标值的最长子序列的长度 - 力扣(LeetCode)


给你一个下标从 0 开始的整数数组 nums 和一个整数 target 。返回和为 target 的 nums 子序列中,子序列 长度的最大值 。如果不存在和为 target 的子序列,返回 -1 。子序列 指的是从原数组中删除一些或者不删除任何元素后,剩余元素保持原来的顺序构成的数组。

(一)回溯 

  • f(i,j) 表示在物品集 nums 的前 i 选取物品,使得装满容量j 的背包有最多个物品
  • 也就是f(i,j) 表示在数组 nums 前 i 个的选取元素,使得这些元素之和等于 j 最长子序列长度
  • dfs(i,j) = max(dfs(i-1,j),dfs(i-1,j-nums[i])+1)
class Solution {
public:// 递归搜索int lengthOfLongestSubsequence(vector<int>& nums, int target) {int n = nums.size();function<int(int,int)>dfs=[&](int i,int s) -> int {if(i<0) { if(s==0) return 0;else return INT_MIN;}return max(dfs(i-1,s),dfs(i-1,s-nums[i])+1);};int ans = dfs(n-1,target);return ans<0?-1:ans;}
};

(二) 递归搜索 + 保存计算结果 = 记忆化搜索

class Solution {
public:// 记忆化递归搜索int lengthOfLongestSubsequence(vector<int>& nums, int target) {int n = nums.size();vector<vector<int>> memo(n,vector<int>(target+1,-1));function<int(int,int)>dfs=[&](int i,int s) -> int {if(i<0) { if(s==0) return 0;else return INT_MIN;}int& res = memo[i][s];if(res != -1) return res;if (s < nums[i]) return res = dfs(i-1,s);return res = max(dfs(i-1,s),dfs(i-1,s-nums[i])+1);};int ans = dfs(n-1,target);return ans<0?-1:ans;}
};
class Solution {
public:// 记忆化递归搜索int lengthOfLongestSubsequence(vector<int>& nums, int target) {int n = nums.size();vector<vector<int>> memo(n+1,vector<int>(target+1,-1));function<int(int,int)>dfs=[&](int i,int s) -> int {if(i<0) { if(s==0) return 0;else return INT_MIN;}int& res = memo[i+1][s];if(res != -1) return res;// 不选int& x = memo[i][s];if(x == -1) x=dfs(i-1,s);if (s < nums[i]) return res=x;// 选int& y = memo[i][s-nums[i]];if(y == -1) y=dfs(i-1,s-nums[i]);return res = max(x,y+1);};int ans = dfs(n-1,target);return ans<0?-1:ans;}
};

(三)1:1 翻译成递推

  • dfs(i,j) = max(dfs(i-1,j),dfs(i-1,j-nums[i])+1)
  • f(i,j) = max(f(i-1,j),f(i-1,j-nums[i])+1);
  • f(i+1,j) = max(f(i,j),f(i,j-nums[i])+1);
class Solution {
public:// 递推int lengthOfLongestSubsequence(vector<int>& nums, int target) {int n = nums.size();vector<vector<int>> f(n+1,vector<int>(target+1,INT_MIN));f[0][0]=0;for(int i=0;i<nums.size();i++) {for(int j=0;j<=target;j++) {// if(j>=nums[i]) f[i+1][j] = max(f[i][j],f[i][j-nums[i]]+1);// else f[i+1][j] = f[i][j];f[i+1][j] = f[i][j];if(j>=nums[i]) f[i+1][j] = max(f[i][j],f[i][j-nums[i]]+1);}}int ans = f[n][target];return ans<0?-1:ans;}
};

进一步优化:

class Solution {
public: // 递推 + 优化int lengthOfLongestSubsequence(vector<int>& nums, int target) {int n = nums.size();vector<vector<int>> f(n+1,vector<int>(target+1,INT_MIN));int sum=0;for(int i=0;i<nums.size();i++) {f[i][0]=0;sum=min(sum+nums[i],target);for(int j=1;j<=sum;j++) {f[i+1][j] = f[i][j];if(j>=nums[i]) f[i+1][j] = max(f[i][j],f[i][j-nums[i]]+1);}}int ans = f[n][target];return ans<0?-1:ans;}
};

>>空间优化

  • 1、二维数组空间优化
class Solution {
public:// 二维空间优化int lengthOfLongestSubsequence(vector<int>& nums, int target) {int n = nums.size();vector<vector<int>> dp(2,vector<int>(target+1,INT_MIN));int sum=0;for(int i=0;i<n;i++) {dp[i%2][0]=0;sum=min(sum+nums[i],target);for(int j=1;j<=sum;j++) {if(j >= nums[i]) dp[(i+1)%2][j] = max(dp[i%2][j],dp[i%2][j-nums[i]]+1);else dp[(i+1)%2][j] = dp[i%2][j];}}int ans = dp[n%2][target];return ans<0?-1:ans;}
};
  • 2.一维空间优化
class Solution {
public:// 一维空间优化int lengthOfLongestSubsequence(vector<int>& nums, int target) {int n = nums.size();vector<int> dp(target+1,INT_MIN);dp[0]=0;int sum=0;for(int i=0;i<n;i++) {sum=min(sum+nums[i],target);for(int j=sum;j>=nums[i];j--) {dp[j] = max(dp[j],dp[j-nums[i]]+1);}}int ans = dp[target];return ans<0?-1:ans;}
};

内容总结来自B站这位up主(Horn_JoJo)的视频简介:(总结得超棒!!!)

动态规划之选或者不选 通过「选」「不选」,确定子问题与原问题的联系。子问题又可以通过同样的「选」或者「不选」来再次找到子子问题与子问题的联系。这样就可以不断将问题拆成子问题。就构成了一个搜索树。当拆分到一定程度时,则找到了最容易解决的子问题。这样就可以先将子问题解决掉,然后反过来解决较大的子问题。这样就可以解决原问题了。

  • 树的根结点时原问题。树的叶子结点是边界或者最小子问题
  • 直接递归(满二叉树本,有重复子问题), 记忆化搜索(递归+记录)减少重复计算。
  • :省略递」的过程,直接「归」的过程中计算。

推荐和参考文章、视频: 

116双周赛T3复盘_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1Zg4y197BR/?spm_id_from=333.788.top_right_bar_window_history.content.click&vd_source=a934d7fc6f47698a29dac90a922ba5a3

动态规划入门:从记忆化搜索到递推_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1Xj411K7oF/?spm_id_from=333.788&vd_source=a934d7fc6f47698a29dac90a922ba5a3

2915. 和为目标值的最长子序列的长度 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/length-of-the-longest-subsequence-that-sums-to-target/solutions/2502839/mo-ban-qia-hao-zhuang-man-xing-0-1-bei-b-0nca/我的往期文章:

leetCode 198.打家劫舍 动态规划入门:从记忆化搜索到递推-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_41987016/article/details/134179583?spm=1001.2014.3001.5501

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

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

相关文章

ubuntu下vscode终端输出出现空白的问题

当终端 输出铺满后 再继续回车 会出现局部空白 这是vscode 的bug&#xff1f;有大佬知道解决办法的可以评论区留言。

Flutter 04 按钮Button和事件处理、弹框Dialog、Toast

一、按钮组件 1、按钮类型&#xff1a; 2、按钮实现效果&#xff1a; import package:flutter/material.dart;void main() {runApp(const MyApp()); }class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);overrideWidget build(BuildContext co…

Stream 流对象的创建与各方法

Stream 流对象的创建与各方法 目录 1.0 Stream 流的说明 2.0 Stream 流对象的创建 2.1 对于 Collection 系列集合创建 Stream 流对象的方式 2.2 对于 Map 系列集合创建 Stream 流对象的方式 2.3 对于数组创建 Stream 流对象的方式 3.0 Stream 流的中间方法 3.1 Stream 流的 …

《算法设计与分析》 蛮力法实验报告一

1.&#xff08;洛谷 P1008&#xff09;将 1,2...9 共 9 个数分成三组,分别组成三个三位数,且使这三个三位数构成 1:2:3 的比例,试求出所有满足条件的三个三位数。 输入格式&#xff1a; 无 输出格式&#xff1a; 若干行&#xff0c;每行 3 个数字。按照每行第 1 个数字升序…

vue基于ElementUI/Plus自定义的一些组件

vue3-my-ElementPlus 源码请到GitHub下载使用MyTable、MySelect、MyPagination 置顶|Top | 使用案例&#xff1a; 1.0 定义表格数据&#xff08;测试使用&#xff09; data() {return {tableData: [],value:[],valueList: [],}; },// 构造表格测试数据// 1 第一行&#xf…

基于nodejs+vue客户管理管理系统

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

【设计模式】第6节:创建型模式之“原型模式”

由于本人现在所使用的语言主要是golang&#xff0c;所以后面的代码主要使用golang编写。语言实现应该不是障碍&#xff0c;主要是理解每种设计模式它的思想。 如果对象的创建成本比较大&#xff0c;而同一个类的不同对象之间差别不大&#xff08;大部分字段都相同&#xff09;…

C/C++苹果和虫子 2021年3月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析

目录 C/C苹果和虫子 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C苹果和虫子 2021年3月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 你买了一箱n个苹果&#xff0c;很不幸的是买完时箱…

数据结构与算法之美学习笔记:15 | 二分查找(上):如何用最省内存的方式实现快速查找功能?

目录 前言无处不在的二分思想O(logn) 惊人的查找速度二分查找的递归与非递归实现二分查找应用场景的局限性解答开篇内容小结 前言 本节课程思维导图&#xff1a; 今天我们讲一种针对有序数据集合的查找算法&#xff1a;二分查找&#xff08;Binary Search&#xff09;算法&am…

win10 + vs2017 + gdal2.0.3 编译

1. 下载并解压gdal2.0.3 我的放置目录是&#xff1a;D:\Depend_3rd_party\gdal2\gdal-2.0.3&#xff0c;其中gdal-2.0.3是解压得到的文件夹 2. 修改 nmake.opt 文件 用notepad打开nmake.opt文件&#xff0c;修改以下三个部分&#xff1a; &#xff08;1&#xff09;修改C co…

程序员想要网上接单却看花了眼?那这几个平台你可得收藏好了!

现在经济压力这么大&#xff0c;但是生活成本还在上升&#xff0c;相信大家都知道“四脚吞金兽”的威力了吧&#xff01;话虽如此&#xff0c;但是生活总得继续&#xff0c;为了家庭的和谐幸福&#xff0c;为了孩子的未来&#xff0c;不少人选择多干几份工作&#xff0c;赚点外…

Macroscope安全漏洞检测工具简介

学习目标&#xff1a; 本介绍旨在帮助感兴趣者尽快了解 Macroscope&#xff0c;这是一款用于安全测试自动化和漏洞管理的企业工具。 全覆盖应用程序安全测试&#xff1a; 如下图所示&#xff0c;如果使用多种互补工具&#xff08;SAST/DAST/SCA 等&#xff09;来检测应用程序…

linux编译boost库并执行程序

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、--prefix命令 二、安装过程 1、shell脚本&#xff1a; 2、gcc编译环境 执行过程 三、linux下执行cpp程序 总结 前言 提示&#xff1a;这里可以添加本文…

【Synopsys工具使用】VCS使用与Makefile脚本调用

文章目录 一、文件导入二、VCS仿真&#xff08;使用可视化界面&#xff09;三、VCS仿真&#xff08;使用Maefile文件&#xff09;3.1 Makefile文件编写3.2 仿真文件编写规范3.3 Makefile文件使用 一、文件导入 新建一个文件夹新建一个文件夹(图中IC_work)   创建一个目录&…

3.18每日一题(奇偶性、奇偶性的平移、几何意义、配方、换元)

解法一&#xff1a;先配方&#xff0c;再用三角函数换元&#xff08;看见根号一般用三角函数&#xff09;&#xff0c;看见对称区间联想奇偶性&#xff0c;最后再用公式 解法二&#xff1a; 利用奇偶性的平移&#xff0c;令&#xff08;x-1&#xff09; t &#xff0c;对应的区…

项目实战:给首页上库存名称添加超链接然后带fid跳转到edit页面

1、提取公共方法common.js function $(key){if(key){if(key.startsWith("#")){key key.substring(1)return document.getElementById(key)}else{let nodeList document.getElementsByName(key)return Array.from(nodeList)}} } 2、 给库存名称添加超链接 2.1、inde…

力扣刷题 day63:11-02

1.字符串中的第一个唯一字符 给定一个字符串 s &#xff0c;找到 它的第一个不重复的字符&#xff0c;并返回它的索引 。如果不存在&#xff0c;则返回 -1 。 方法一&#xff1a;两次遍历哈希表 #方法一&#xff1a;两次遍历哈希表 def firstUniqChar(s):d{}for i in s:if …

数据库 | 看这一篇就够了!最全MySQL数据库知识框架!

大家好&#xff01; 作为一名程序员&#xff0c;每天和各种各样的“数据库”打交道&#xff0c;已经成为我们的日常。当然&#xff0c;立志成为一名超级架构师的我&#xff0c;肯定要精通这项技能。咳咳&#xff01;不过饭还是要一口一口吃的&#xff0c;“数据库”这个内容实在…

Linux Makefile变量详解

前言 我们是地球人。曾经为复杂的 Makefile 变量而苦恼过吗&#xff1f;这就是我们的用武之地。我们简化您的构建流程&#xff0c;以获得更快、更高效的结果。看看我们。 自 1976 年出现以来&#xff0c;Make 一直在帮助开发人员自动执行编译代码、构建可执行文件和生成文档的…

【Proteus仿真】【51单片机】贪吃蛇游戏

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使用8*8LED点阵、按键模块等。 主要功能&#xff1a; 系统运行后&#xff0c;可操作4个按键控制小蛇方向。 二、软件设计 /* 作者&#xff1a;嗨小易…