具有「线性」阶段划分的动态规划方法统称为线性动态规划(简称为「线性 DP」),如下图所示。

一、概念

如果状态包含多个维度,但是每个维度上都是线性划分的阶段,也属于线性 DP。比如背包问题、区间 DP、数位 DP 等都属于线性 DP。

线性 DP 问题的划分方法有多种方式。

  • 如果按照「状态的维度数」进行分类,我们可以将线性 DP 问题分为:一维线性 DP 问题、二维线性 DP 问题,以及多维线性 DP 问题。
  • 如果按照「问题的输入格式」进行分类,我们可以将线性 DP 问题分为:单串线性 DP 问题、双串线性 DP 问题、矩阵线性 DP 问题,以及无串线性 DP 问题。

二、单串线性 DP 问题

1. 问题

单串线性 DP 问题:问题的输入为单个数组或单个字符串的线性 DP 问题。状态一般可定义为 dp[i],表示为:

  1. 「以数组中第 i个位置元素 nums[i]] 为结尾的子数组(nums[0]...nums[i])」的相关解。
  2. 「以数组中第 i−1个位置元素 nums[i−1]为结尾的子数组(nums[0]...nums[i−1])」的相关解。
  3. 「以数组中前 i个元素为子数组(nums[0]...nums[i−1])」的相关解

这 3 种状态的定义区别在于相差一个元素 nums[i]。

  1. 第 1种状态:子数组的长度为 i+1,子数组长度不可为空;
  2. 第 2 种状态、第 3 种状态:这两种状态描述是相同的。子数组的长度为 i,子数组长度可为空。在 i=0时,方便用于表示空数组(以数组中前 0 个元素为子数组)

三、最长递增子序列

单串线性 DP 问题中最经典的问题就是「最长递增子序列(Longest Increasing Subsequence,简称 LIS)」。

1. 实战练习

给定一个整数数组 nums,找到其中最长严格递增子序列的长度

  • 子序列:由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
  • 1≤nums.length≤2500。
  • −10^4≤nums[i]≤10^4。

2. 代码

class Solution {// 定义长度最长递增子序列的方法lengthOfLIS(nums) {// 获取数组的长度const size = nums.length;// 创建并初始化动态规划数组,初始值为1const dp = new Array(size).fill(1);// 外层循环迭代每个元素for (let i = 0; i < size; i++) {// 内层循环迭代当前元素之前的元素for (let j = 0; j < i; j++) {// 如果当前元素大于之前的元素,可以将当前元素加入递增子序列if (nums[i] > nums[j]) {// 更新以当前元素结尾的递增子序列的长度dp[i] = Math.max(dp[i], dp[j] + 1);}}}// 返回动态规划数组中的最大值,即为最长递增子序列的长度return Math.max(...dp);}
}// 示例用法
const solution = new Solution();
// 输出最长递增子序列的长度
console.log(solution.lengthOfLIS([10, 9, 2, 5, 3, 7, 101, 18]));

四、最大子数组和

单串线性 DP 问题中除了子序列相关的线性 DP 问题,还有子数组相关的线性 DP 问题。

注意

  • 子序列:由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。
  • 子数组:指的是数组中的一个连续子序列。

「子序列」与「子数组」都可以看做是原数组的一部分,而且都不会改变原来数组中元素的相对顺序。其区别在于数组元素是否要求连续。

1. 实战练习

给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和

2. 代码

class Solution {maxSubArray(nums) {// 获取数组的长度const size = nums.length;// 创建并初始化动态规划数组,初始值为0const dp = new Array(size).fill(0);// 初始化动态规划数组的第一个元素dp[0] = nums[0];// 从数组的第二个元素开始遍历for (let i = 1; i < size; i++) {// 如果前一个元素的动态规划值小于0,说明不利于累积当前元素,直接以当前元素为起点重新计算if (dp[i - 1] < 0) {dp[i] = nums[i];} else {// 否则,累积当前元素,更新动态规划值dp[i] = dp[i - 1] + nums[i];}}// 返回动态规划数组中的最大值,即为最大子数组和return Math.max(...dp);}
}// 示例用法
const solution = new Solution();
// 输出最大子数组和
console.log(solution.maxSubArray([-2, 1, -3, 4, -1, 2, 1, -5, 4]));

五、最长的斐波那契子序列的长度

有一些单串线性 DP 问题在定义状态时需要考虑两个结束位置,只考虑一个结束位置的无法清楚描述问题。这时候我们就需要需要增加一个结束位置维度来定义状态

1. 实战练习

给定一个严格递增的正整数数组 arr,从数组 arr 中找出最长的斐波那契式的子序列的长度。如果不存斐波那契式的子序列,则返回 0。

2. 代码

class Solution {lenLongestFibSubseq(arr) {const size = arr.length;let ans = 0;// 枚举所有可能的前两个数for (let i = 0; i < size; i++) {for (let j = i + 1; j < size; j++) {let tempAns = 0;let tempI = i;let tempJ = j;let k = j + 1;// 在数组中搜索斐波那契子序列while (k < size) {// 如果当前三个数满足斐波那契关系if (arr[tempI] + arr[tempJ] === arr[k]) {tempAns += 1;tempI = tempJ;tempJ = k;}k += 1;}// 更新最大斐波那契子序列长度if (tempAns > ans) {ans = tempAns;}}}// 如果找到了斐波那契子序列,返回长度加上初始的两个数if (ans > 0) {return ans + 2;} else {return ans;}}
}// 示例用法
const solution = new Solution();
// 输出最长斐波那契子序列的长度
console.log(solution.lenLongestFibSubseq([1, 2, 3, 4, 5, 6, 7, 8])); 

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

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

相关文章

Rust 学习笔记:使用自定义命令扩展 Cargo

Rust 学习笔记&#xff1a;使用自定义命令扩展 Cargo Rust 学习笔记&#xff1a;使用自定义命令扩展 Cargo Rust 学习笔记&#xff1a;使用自定义命令扩展 Cargo Cargo 支持通过 $PATH 中的 cargo-something 形式的二进制文件拓展子命令&#xff0c;而无需修改 Cargo 本身。 …

NodeMediaEdge任务管理

NodeMediaEdge任务管理 简介 NodeMediaEdge是一款部署在监控摄像机网络前端中&#xff0c;拉取Onvif或者rtsp/rtmp/http视频流并使用rtmp/kmp推送到公网流媒体服务器的工具。 在未使用NodeMediaServer的情况下&#xff0c;或是对部分视频流需要单独推送的需求&#xff0c;也可…

蒲公英盒子连接问题debug

1、 现象描述 2、问题解决 上图为整体架构图&#xff0c;其中左边一套硬件设备是放在机房&#xff0c;右边是放在办公室。左边的局域网连接了可以访问外网的路由器&#xff0c;利用蒲公英作为旁路路由将局域网暴露在外网环境下。 我需要通过蒲公英作为旁路路由来进行远程访问&…

Golang 依赖注入:构建松耦合架构的关键技术

依赖注入&#xff08;Dependency Injection, DI&#xff09; 是一种设计模式&#xff0c;用于实现控制反转&#xff08;Inversion of Control, IoC&#xff09;&#xff0c;通过将依赖项的创建和管理交给外部组件&#xff0c;而不是在类或函数内部直接创建依赖项&#xff0c;从…

Transformer核心原理

简介 在人工智能技术飞速发展的今天&#xff0c;Transformer模型凭借其强大的序列处理能力和自注意力机制&#xff0c;成为自然语言处理、计算机视觉、语音识别等领域的核心技术。本文将从基础理论出发&#xff0c;结合企业级开发实践&#xff0c;深入解析Transformer模型的原…

虚拟线程与消息队列:Spring Boot 3.5 中异步架构的演进与选择

企业级开发领域正在经历一场翻天覆地的巨变&#xff0c;然而大多数开发者却对此浑然不觉&#xff0c;完全没有意识到。Spring Boot 3.5 带来的革命性的虚拟线程 (Virtual Threads) 和增强的响应式能力&#xff0c;绝不仅仅是小打小闹的增量改进——它们正在从根本上改变我们对异…

网络编程(计算机网络基础)

认识网络 1.网络发展史 ARPnetA(阿帕网)->internet(因特网)->移动互联网->物联网 2.局域网与广域网 局域网 概念&#xff1a;的缩写是LAN&#xff08;local area network&#xff09;&#xff0c;顾名思义&#xff0c;是个本地的网络&#xff0c;只能实现小范围短距…

Windows Server部署Vue3+Spring Boot项目

在Windows Server 上部署Vue3 Spring Boot前后端分离项目的详细步骤如下&#xff1a; 一、环境准备 安装JDK 17 下载JDK MSI安装包&#xff08;如Oracle JDK 或 OpenJDK&#xff09; 双击安装&#xff0c;配置环境变量&#xff1a; JAVA_HOME&#xff1a;JDK安装路径&#xf…

CCF CSP 第37次(2025.03)(3_模板展开_C++)(哈希表+stringstream)

CCF CSP 第37次&#xff08;2025.03&#xff09;&#xff08;3_模板展开_C&#xff09; 解题思路&#xff1a;思路一&#xff08;哈希表stringstream&#xff09;&#xff1a; 代码实现代码实现&#xff08;思路一&#xff08;哈希表stringstream&#xff09;&#xff09;&…

数据安全管理进阶:81页 2024数据安全典型场景案例集【附全文阅读】

《2024 数据安全典型场景案例集》聚焦政务数据安全&#xff0c;覆盖数据细粒度治理、授权运营、接口安全、系统接入、批量数据共享、使用侧监管、风险监测、账号管控、第三方人员管理、密码应用等十大典型场景&#xff0c;剖析各场景风险并提供技术方案&#xff0c;如基于 AI 的…

Leetcode 261. 以图判树

1.题目基本信息 1.1.题目描述 给定编号从 0 到 n - 1 的 n 个结点。给定一个整数 n 和一个 edges 列表&#xff0c;其中 edges[i] [ai, bi] 表示图中节点 ai 和 bi 之间存在一条无向边。 如果这些边能够形成一个合法有效的树结构&#xff0c;则返回 true &#xff0c;否则返…

【ISAQB大纲解读】LG 1-8:区分显性陈述和隐性假设(R1)

软件架构师&#xff1a; 应明确提出假设或先决条件&#xff0c;从而防止隐性假设 知道隐性假设可能会导致利益相关方之间的潜在误解 1. 应明确提出假设或先决条件&#xff0c;防止隐性假设 为什么重要&#xff1f; 隐性假设是架构风险的温床 例如&#xff1a;假设“所有服务都…

IT运维工具的选择标准有哪些?

选择IT运维工具时&#xff0c;可参考以下标准&#xff0c;确保工具适配业务需求且高效易用&#xff1a; 1. 明确业务需求与场景 • 核心目标&#xff1a;根据运维场景&#xff08;如监控、自动化、安全等&#xff09;匹配工具功能。例如&#xff0c;监控大规模集群选Promethe…

MySQL 核心知识整理【一】

一、MySQL存储引擎对比&#xff1a;InnoDB vs MyISAM 在使用MySQL时&#xff0c;选择合适的存储引擎对性能影响很大。最常见的两个引擎是 InnoDB 和 MyISAM&#xff0c;它们各自的设计目标不同&#xff0c;适用场景也不一样。 事务与数据安全性方面&#xff0c;InnoDB 支持事…

人工智能在智能制造业中的创新应用与未来趋势

随着工业4.0和智能制造的快速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术正在深刻改变制造业的各个环节。从生产自动化到质量检测&#xff0c;从供应链优化到设备维护&#xff0c;AI的应用不仅提高了生产效率&#xff0c;还提升了产品质量和企业竞争力。本文将探讨…

arc3.2语言sort的时候报错:(sort < `(2 9 3 7 5 1)) 需要写成这种:(sort > (pair (list 3 2)))

arc语言sort的时候报错&#xff1a;(sort < (2 9 3 7 5 1)) arc> (sort < (2 9 3 7 5 1)) Error: "set-car!: expected argument of type <pair>; given: 9609216" arc> (sort < (2 9 3 )) Error: "Function call on inappropriate object…

Ubuntu 24.04 LTS Chrome 中文输入法(搜狗等)失效?一行命令解决

Ubuntu 24.04 LTS Chrome 中文输入法&#xff08;搜狗等&#xff09;失效&#xff1f;一行命令解决 在 Ubuntu 24.04 LTS 中&#xff0c;如果你发现 Chrome 浏览器用不了搜狗输入法或其他 Fcitx5 中文输入法&#xff0c;可以试试下面的方法。 直接上解决方案&#xff1a; 打…

大模型前处理-CPU

前处理包含哪些流程 分词 tokenizationembedding CPU可以做哪些优化 分词 分词在做什么&#xff1f; 什么是词元化&#xff1f; 词元化&#xff08;Tokenization&#xff09;是把一段自然语言文本拆分成更小的单元&#xff08;称为“词元”&#xff0c;即 Token&#xff0…

Kafka数据怎么保障不丢失

在分布式消息系统中&#xff0c;数据不丢失是核心可靠性需求之一。Apache Kafka 通过生产者配置、副本机制、持久化策略、消费者偏移量管理等多层机制保障数据可靠性。以下从不同维度解析 Kafka 数据不丢失的核心策略&#xff0c;并附示意图辅助理解。 一、生产者端&#xff1a…

图像处理篇---face_recognition库实现人脸检测

以下是使用face_recognition库实现人脸检测的详细步骤、实例代码及解释&#xff1a; 一、环境准备 1. 安装依赖库 pip install face_recognition opencv-python # 核心库 pip install matplotlib # 用于显示图像&#xff08;可选&#xff09;2. 依赖说明 face_recognitio…