动态规划之两个数组的 dp(上)
文章目录
- 最长公共子序列
- 不相交的线
- 不同的子序列
- 通配符匹配
最长公共子序列
题目:最长公共子序列

思路
选取
s1的[0, i]区间以及s2的[0, j]区间作为研究对象
-
状态表示:
dp[i][j]表示,s1的[0, i]区间以及s2的[0, j]区间内所有的子序列中,最长公共子序列的长度 -
状态转移方程:
s1[i] == s2[j]时,即最长公共子序列以s1[i]结尾,所以有dp[i][j] = dp[i - 1][j - 1] + 1s1[i] != s2[j]时,最长公共子序列一定不以s1[i]结尾,所以- 去
s1的[0, i - 1]区间以及s2的[0, j]区间寻找答案,即dp[i][j] = dp[i - 1][j] - 去
s1的[0, i]区间以及s2的[0,j - 1 ]区间寻找答案,即dp[i][j] = dp[i][j - 1] - 去
s1的[0, i - 1]区间以及s2的[0, j - 1]区间寻找答案,即dp[i][j] = dp[i - 1][j - 1]
- 综上,
1和2以及包括3,所以dp[i][j] = max(dp[i][j - 1], dp[i - 1][j])
- 去
-
初始化:引入空串,帮助我们初始化
在s1, s2前添加一个空字符,也就是说s1[0]和s2[0]的位置的值是空串;
dp表的大小为(m+1) x (n+1),其中m和n是s1和s2的长度。初始化时,将第一行和第一列的值都设置为0
注意下标的映射 -
填表顺序:每次
i和j都需要用到i - 1和j - 1,所以从上往下填,从左往右填 -
返回值:
dp[m][n],其中m和n是s1和s2的长度
C++代码
class Solution
{
public:int longestCommonSubsequence(string text1, string text2) {int m = text1.size(), n = text2.size();vector<vector<int>> dp(m + 1, vector<int>(n + 1));for(int i = 1; i <= m; i++)for(int j = 1; j <= n; j++)if(text1[i - 1] == text2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);return dp[m][n];}
};
不相交的线
题目:不相交的线

思路
阅读本题后发现和上题解法基本相同
C++代码
class Solution
{
public:int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {int m = nums1.size(), n = nums2.size();vector<vector<int>> dp(m + 1, vector<int>(n + 1));for (int i = 1; i <= m; i++)for (int j = 1; j <= n; j++)if (nums1[i - 1] == nums2[j - 1])dp[i][j] = dp[i - 1][j - 1] + 1;elsedp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);return dp[m][n];}
};
不同的子序列
题目:不同的子序列

思路
选取
t的[0, i]区间以及s的[0, j]区间作为研究对象
- 状态表示:
dp[i][j]表示,s的[0, j]区间内所有的子序列中,有多少个t的[0, i]区间内的子串 - 状态转移方程:根据
s的子序列包不包含s[j]来划分- 包含
s[j]时,t[i] == s[j],此时dp[i][j] = dp[i - 1][j - 1] - 不包含
s[j]时,此时dp[i][j] = dp[i][j - 1]
- 包含
- 初始化:引入空串,注意下标的映射,
- 当
t为空时,s中至少有一个空串是其子串,所以第一行为1 - 当
s为空时,t只有是空串时,符合题意,第一列除了第一个都是0
- 当
- 填表顺序:
i和j填写都需要用到i - 1和j - 1,所以从上往下填,从左往右填 - 返回值:
dp[m][n],其中m和n是t和s的长度
C++代码
class Solution
{
public:int numDistinct(string s, string t) {int m = t.size(), n = s.size();vector<vector<double>> dp(m + 1, vector<double>(n + 1));for(int j = 0; j <= n; j++) dp[0][j] = 1;for(int i = 1; i <= m; i++)for(int j = 1; j <= n; j++){dp[i][j] += dp[i][j - 1];if(t[i - 1] == s[j - 1]) dp[i][j] += dp[i - 1][j - 1];}return dp[m][n];}
};
通配符匹配
题目:通配符匹配

思路
选取选取第一个字符串
[0, i]区间以及第二个字符串[0, j]区间作为研究对象
-
状态表示:
dp[i][j]表示,p的[0, j]区间内的子串中,能否匹配s的[0, i]区间内的子串 -
状态转移方程:根据根据最后一个位置的元素,来讨论
p[j]是普通字符,s[i] == p[j] && dp[i - 1][j - 1] == true ->truep[j] == '?',dp[i - 1][j - 1] == true -> truep[j] == '*'- 匹配空串,
dp[i][j - 1] - 匹配一个字符
s[i],dp[i - 1][j - 1] - 匹配两个字符
s[i]、s[i - 1],dp[i - 2][j - 1] ... ... ... ...
优化
p[j] == '*'-
- 我们注意到
dp[i][j] = dp[i][j -2] || dp[i - 1][j - 2] || dp[i -2][j -2] || ... ...dp[i - 1][j] = dp[i - 1][j -2] || dp[i - 2][j - 2] || dp[i -3][j -2] || ... ...- 所以,
dp[i][j] = dp[i][j - 1] || dp[i - 1][j] -
- 匹配空串,
dp[i][j - 1] - 匹配一个,但不舍去
*,dp[i - 1][j] - 所以,
dp[i][j] = dp[i][j - 1] || dp[i - 1][j]
- 匹配空串,
-
初始化:引入空串,注意下标的映射,
- 初始化整个数组为
false dp[0][0]表示两个空串是否匹配,初始化为true- 第一行表示
s为空串,p串与空串只有一种匹配可能,即 p 串表示为"***",此时也相当于空串匹配上空串,将所有前导为"*"的p子串与空串的dp值设为true
- 初始化整个数组为
-
填表顺序:
i和j填写都需要用到i - 1和j - 1,所以从上往下填,从左往右填 -
返回值:
dp[m][n],其中m和n是s和p的长度
C++代码
class Solution
{
public:bool isMatch(string s, string p) {int m = s.size(), n = p.size();vector<vector<bool>> dp(m + 1, vector<bool>(n + 1));s = " " + s;p = " " + p;dp[0][0] = true;for(int j = 1; j <= n; j++)if(p[j] == '*') dp[0][j] = true;else break;for(int i = 1; i <= m; i++)for(int j = 1; j <= n; j++){if(p[j] == '*')dp[i][j] = dp[i - 1][j] || dp[i][j - 1];elsedp[i][j] = (p[j] == '?' || s[i] == p[j]) && dp[i -1][j - 1];}return dp[m][n];}
};相关文章:
动态规划之两个数组的 dp(上)
文章目录 最长公共子序列不相交的线不同的子序列通配符匹配 最长公共子序列 题目:最长公共子序列 思路 选取s1的[0, i]区间以及s2的[0, j]区间作为研究对象 状态表示:dp[i][j]表示,s1的[0, i]区间以及s2的[0, j]区间内…...
DC-9靶机通关
这是这个系列的最后一个靶机了!!!经过前面的锻炼和学习,这次我的目标是尽量不借助任何教程或者提示来拿下这个靶机!!!下面我们看能不能成功!!! 1.实验环境 攻…...
前端注释都应该怎么写?
以下是一些前端注释的例子,展示了如何应用前面提到的建议: 1. 使用清晰、简洁的语言 // 计算两个数的平均值 function calculateAverage(a, b) {return (a b) / 2; }2. 描述代码的目的和功能 // 将日期格式化为 "YYYY-MM-DD" 的字符串 fun…...
深入解析缓存模式下的数据一致性问题
今天,我们来聊聊常见的缓存模式和数据一致性问题。 常见的缓存模式有:Cache Aside、Read Through、Write Through、Write Back、Refresh Ahead、Singleflight。 缓存模式 Cache Aside 在 Cache Aside 模式中,是把缓存当做一个独立的数据源…...
嵌入式常用功能之通讯协议1--IIC
嵌入式常用功能之通讯协议1--串口 嵌入式常用功能之通讯协议1--IIC(本文) 嵌入式常用功能之通讯协议1--SPI 一、IIC总线协议介绍 Inter-Integrated Circuit(集成电路总线),是由 Philips 半导体公司(现在的 NXP 半导体…...
【Wi-Fi】Wi-Fi 7(802.11be) Vs Wi-Fi 8 (802.11bn)
介绍 WiFi 7 (802.11be) 是 WiFi-6 (802.11ax) 的继任者,旨在提高数据速率并减少拥挤环境中的延迟。 WiFi 8 (8021.1bn)是后续标准,专注于提高 WLAN 连接的可靠性, 提高…...
Ubuntu软件包管理机制
文章目录 🍊自我介绍🍊Ubuntu软件包管理机制🍊软件安装命令详解: 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞关注评论收藏(一键四连)哦~ 🍊自我介绍 Hello,大家好…...
SpringBoot详解:概念、优点、运行方式、配置文件、异步请求及异常处理
一、什么是SpringBoot? SpringBoot是一个基于Spring框架的开源项目,它简化了Spring应用的初始搭建以及开发过程。它提供了自动配置、起步依赖、Actuator、命令行界面等特性,使得开发者可以快速构建出一个独立、生产级别的Spring应用。 二、…...
npm install -g @vue/cil 非常卡慢
安装 vue/cli 时遇到卡慢的情况通常和网络问题有关,特别是国内的网络环境下访问 npm 的服务器可能较慢。你可以尝试以下几种方法来加速: 使用淘宝镜像源 淘宝 NPM 镜像源对国内用户更加友好。你可以临时使用淘宝镜像源安装 vue/cli: npm inst…...
Windows 基础 (二):系统目录与环境变量
内容预览 ≧∀≦ゞ Windows 基础 2:系统目录与环境变量声明系统目录系统核心目录其他重要日志目录应用程序数据目录用户数据目录隐藏目录 环境变量1. 查看环境变量2. 设置永久环境变量3. 查看特定环境变量的值4. 环境变量的存储位置5. 自定义环境变量的应用 结语 Wi…...
World of Warcraft [CLASSIC][80][the Ulduar] BOSS 05 06 07
BOSS-05-钢铁议会 BOSS-06-科隆加恩(无困难模式) BOSS-07-欧尔莉亚(无困难模式)...
World of Warcraft [CLASSIC][80][the Ulduar] BOSS 12 13
BOSS-12-维扎克斯将军 BOSS-13-尤格萨隆...
第一篇 硬件篇1[学习-来自 正点原子]
在电路设计中,TVS(瞬态电压抑制器)是一种有效的保护元件,可以用来防止瞬时过电压对芯片和其他敏感器件造成损坏。 STM32F103RCT6作为MCU 一键下载电路的具体实现过程: 首先, mcuisp控制 DTR输出低电平&…...
【TextIn:开源免费的AI智能文字识别产品(通用文档智能解析识别、OCR识别、文档格式转换、篡改检测、证件识别等)】
TextIn:开源免费的AI智能文字识别产品(通用文档智能解析识别、OCR识别、文档格式转换、篡改检测、证件识别等) 产品的官网:TextIn官网 希望感兴趣以及有需求的小伙伴们多多了解,因为这篇文章也是源于管网介绍才产出的…...
C++语言有哪些常用语句?
1. 变量定义语句 在 C 中,首先要定义变量才能使用。例如 int a;定义了一个整型变量a。这是很基础的语句,它告诉编译器为变量a分配内存空间,用于存储整数值。 如果要定义多个相同类型的变量,可以写成 int a, b, c;除了基本数据类…...
linux alsa-lib snd_pcm_open函数源码分析(二)
访问原版内容,可直接到博客 linux alsa-lib snd_pcm_open函数源码分析(二) https://blog.whatsroot.xyz/2020/08/12/alsa_snd_open-analysis-2/ 系列文章其他部分: linux alsa-lib snd_pcm_open函数源码分析(一) linux alsa-lib snd_pc…...
机翼的抖振与颤振
机翼的抖振与颤振 1. 机翼颤振:飞机设计的隐形杀手2. 机翼抖振:由气流不稳定性引起的振动3. 两种振动的区分和管理3.1 检测与预防 机翼的颤振和抖振是飞机设计和航空工程师面临的两个重要技术问题。这两种现象虽然都与机翼的振动相关,但它们的…...
React04 State变量 组件渲染
State变量 & 渲染和提交 State 变量state 变量的使用State 是隔离且私有的 组件渲染 State 变量 state 变量的使用 导入 useState import { useState } from react;定义一个 state 变量 const [index, setIndex] useState(0);useState 的唯一参数是 state 变量的初始值…...
【数据库系统概论】第3章 关系数据库标准语言SQL(一)数据查询(超详细)
目录 一、单表查询 1. 简单的数据查询 (1)选择表中若干列 (2)选择表中若干行(元祖) 2. 聚合函数与分组查询 聚集函数 GROUP BY分组查询 二、联接查询 1、连接概述 2. 内联接(INNER JO…...
mysql-恢复数据(日志管理)
前言 在mysql中我们有时候会出现误删除,或者其他的问题,我们可以通过mysql的日志进行恢复 操作 我们可以在mysql里面定义一个错误日志,方便我们可以排查是因为什么原因来解决mysql无法启动问题 ----------------------------------------…...
【2026 最新】Web 安全完整学习指南 红队全套技能栈
0x00 技能栈 依照红队的流程分工,选择适合自己的技能栈发展。 越接近中心的能力点越贴近web技术栈,反之亦然。可以根据自身情况,选择技术栈的发展方向。 0x01 漏洞理解篇(Vulnerability) 1.1 前端 同源策略 & CSP & JOSNP 跨域…...
Vibe Coding 工具选型决策树:5 类项目场景对应 7 种组合配置方案
1. 项目概述:为什么“选对组合”比“选对单个工具”更重要 大多数人第一次听说 vibe coding,是在看到某位工程师用 Cursor 写完一个 Vue3 表单组件只花了 90 秒,或者用 Claude Code 在 VS Code 里补全了整套 Express 路由逻辑后脱口而出的那句“这哪是写代码,这是调 API”…...
GitHub 协作完全指南:从“傻瓜”到专家的保姆级教程
引言:为什么协作会让人头疼?想象一下,你和其他几个人要一起画一幅巨大的壁画。每个人都在自己的小画板上画一部分。问题来了:怎么保证大家用的颜色一致?怎么把每个人的画拼到一起时严丝合缝?如果两个人画了…...
为什么你的课程推荐越来越不准?Perplexity查询功能2024Q2算法升级内幕(附绕过冷启动限制的私有指令)
更多请点击: https://kaifayun.com 第一章:为什么你的课程推荐越来越不准?Perplexity查询功能2024Q2算法升级内幕(附绕过冷启动限制的私有指令) Perplexity 在 2024 年第二季度对课程推荐核心查询模块进行了深度重构&…...
终极Windows更新修复指南:5分钟解决系统更新问题
终极Windows更新修复指南:5分钟解决系统更新问题 【免费下载链接】Reset-Windows-Update-Tool Troubleshooting Tool with Windows Updates (Developed in Dev-C). 项目地址: https://gitcode.com/gh_mirrors/re/Reset-Windows-Update-Tool 你是否遇到过Wind…...
【STM32入门教程】将`printf`重定向到USART串口(以USB转串口为例)
【STM32入门教程】将printf重定向到USART串口(以USB转串口为例) 在STM32开发中,printf是一个非常方便的调试工具。但默认情况下,printf会输出到标准输出设备(如屏幕),而在嵌入式系统中ÿ…...
3步掌握SacreBLEU:让机器翻译评估变得简单可靠
3步掌握SacreBLEU:让机器翻译评估变得简单可靠 【免费下载链接】sacrebleu Reference BLEU implementation that auto-downloads test sets and reports a version string to facilitate cross-lab comparisons 项目地址: https://gitcode.com/gh_mirrors/sa/sacr…...
IDEA里Git冲突别慌!手把手教你用Rebase和Merge搞定,附代码消失急救指南
IDEA中Git冲突与代码消失的终极解决方案:Rebase与Merge实战指南 在团队协作开发中,Git冲突如同程序员日常的"必修课",而IDEA作为Java开发者最信赖的IDE,其内置的Git工具链却常被低估。当你在深夜赶进度时突然遭遇冲突警…...
企业级应用如何通过Taotoken实现API Key的精细化管理与审计
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 企业级应用如何通过Taotoken实现API Key的精细化管理与审计 在构建基于大模型的企业级应用时,API Key的管理与安全审计…...
WCH RISC-V MCU开发:在MounRiver Studio里一键切换GCC8和GCC12工具链(附内存占用对比)
WCH RISC-V MCU开发实战:MounRiver Studio工具链切换与性能优化指南 对于嵌入式开发者而言,选择合适的编译器工具链往往能在资源受限的MCU环境中带来显著性能提升。WCH基于RISC-V架构的微控制器凭借其高性价比和丰富外设资源,正逐渐成为物联网…...
