动态规划之两个数组的 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] + 1
s1[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 ->true
p[j] == '?'
,dp[i - 1][j - 1] == true -> true
p[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无法启动问题 ----------------------------------------…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...

搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

DeepSeek越强,Kimi越慌?
被DeepSeek吊打的Kimi,还有多少人在用? 去年,月之暗面创始人杨植麟别提有多风光了。90后清华学霸,国产大模型六小虎之一,手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水,单月光是投流就花费2个亿。 疯…...