dp(动态规划)之最长公共子序列

动态规划 最长公共子序列 过程图解 1.基本概念       首先需要科普一下,最长公共子序列(longest common sequence)和最长公共子串(longest common substring)不是一回事儿。什么是子序列呢?即一个给定的序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果。什么是子串呢?给定串中任意个连续的字符组成的子序列称为该串的子串。给一个图再解释一下:        如 阅读详情

今天分享一道比较典型的dp问题:
问题描述:

我们有两个字符串m和n,如果它们的子串a和b内容相同,则称a和b是m和n的公共子序列。子串中的字符不一定在原字符串中连续。
例如字符串“abcfbc”和“abfcab”,其中“abc”同时出现在两个字符串中,因此“abc”是它们的公共子序列。此外,“ab”、“af”等都是它们的字串。
现在给你两个任意字符串(不包含空格),请帮忙计算它们的最长公共子序列的长度。

来源链接:https://www.nowcoder.com/questionTerminal/9ae56e5bdf4f480387df781671db5172
来源:牛客网

解题思想:首先这道题用常规思维来想,很容易让人思考越陷越深,因为两个字符串的比较情况太多了,这道题我拿到的第一反应就是要拿dp解决,首先dp最难的就是要找到他的初始已知条件和dp递推公式,这道题呢用dp状态矩阵来解决,首先dp状态矩阵就表示的是两个字符串各个位的最长公共子序列长度。
针对题里的输入的例子的图例如下:
在这里插入图片描述
首先初始条件可以是dp [0] [0] ,看两个字符串下标都为0时的字符是否是相等的,如果相等的话,则dp[0][0]为1,否则为0 ;接下来要处理的就是两个边界特殊情况比如i=0,j为任意 这时处于矩阵的最上面一行,这时dp[0][j]就只会是他前面的一个状态dp[0][j-1]的结果以及他自身dp[0][j]的结果(自身的这个dp[0][j]可以要看此时的s1[0]和s2[j]是否相等,相等则为1,否则为0)有关;令一种情况i为任意,j=0的情况同上;这两个边界情况处理完后,就是一般情况了dp[i][j] = max(dp[i-1][j],dp[i][j-1]),因为此时这两种情况都可以到dp[i][j],所以要取最大的一个,中间当然也会出现s1[i]=s2[j]的情况,这时就是dp[i-1][j-1]+1和dp[i][j]本身之间取最大值,因为如果此时s1[i]=s2[j]的话则dp[i-1][j-1](s1的i和s2的j同时-1之后的dp状态)加上一个字符的话就是dp[i][j],所以此时dp[i][j]=max(dp[i-1][j-1]+1,dp[i][j])。

在思考这个问题的时候i,j就s1和s2的下标!!!
全程需要注意数组下标不要越界!!!

实现代码:

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

int main()
{
	string s1, s2;
	while (cin >> s1 >> s2){
		int len1 = s1.size();
		int len2 = s2.size();
		vector<vector<int>> dp(len1, vector<int>(len2, 0));
		dp[0][0] = (s1[0] == s2[0]) ? 1 : 0;  //初始已知条件
		for (int i = 1; i < len1; i++){       //特殊上边界
			dp[i][0] = (s1[i] == s2[0]) ? 1 : 0;
			dp[i][0] = max(dp[i - 1][0], dp[i][0]);
		}
		for (int j = 1; j < len2; j++){      //特殊左边界
			dp[0][j] = (s1[0] == s2[j]) ? 1 : 0;
			dp[0][j] = max(dp[0][j - 1], dp[0][j]);
		}
		for (int i = 1; i < len1; i++){      //一般情况
			for (int j = 1; j < len2; j++){
				dp[i][j] = max(dp[i - 1][j],dp[i][j - 1]);
				if (s1[i] == s2[j])
					dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
			}
		}
		cout << dp[len1 - 1][len2 - 1] << endl;   //返回当然是dp[len1-1][len2-1],注意下标一定不要越界
	}
	return 0;
}

运行结果:
在这里插入图片描述

DP系列-最长公共子串和最长公共子序列总结 知识点: 最长公共子串问题是寻找两个或多个已知字符串最长的子串。 此问题与最长公共子序列问题的区别在于子序列不必是连续的,而子串却必须是。 例如: str1="123ABCD4567" str2 ="ABE12345D6" 最长公共子串是:123 最长公共子序列是:123456 1.最长公共子串 题目描述: 计算两个字符串的最大公共字串的长度,字符不区分大小写。 ... 阅读详情

相关推荐

【NOJ1041】【算法实验四】【DP_动态规划】最长公共子序列

1041.最长公共子序列 时限:1000ms 内存限制:200000K  总时限:3000ms 描述 一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X=&lt;x1, x2,…, xm&gt;,则另一序列Z=&lt;z1, z2,…, zk&gt;是X的子序列是指存在一个严格递增的下标序列 &lt;i1, i2,…, ik&gt;,使得对于所有j=1,2,…,...

夏至是个程序媛 1683

【算法】最长公共子序列&编辑距离(两个序列之间的DP)

这两道题目的类似点在于都是比较两个序列之间的内容,这种情况下通常定义 dp 数组为:dp[m + 1][n + 1] (之所以 + 1 是为了方式遍历的过程中出现负数下标)与之对应,遍历元素的时候,使用的下标分别是 i - 1 和 j - 1。(因为原始数据的数据范围还是 0 ~ m 和 0~ n)由于无后效性,即 dp[i][j] 的数值只与和它接近的几个数字有关,因此可以优化 dp 数组的空间。

小威的博客 863

动态规划---例题2.最长公共子序列问题

本题与力扣主站1143题相同. 一.问题描述 一个给定序列的子序列是在该序列中删去若干元素后得到的序列。 确切地说,若给定序列X=<x1, x2,…, xm>,则另一序列Z=<z1, z2,…, zk>是X的子序列是指存在一个严格递增的下标序列 <i1, i2,…, ik>,使得对于所有j=1,2,…,k有 例如,序列Z=<B,C,D,B>是序列X=<A,B,C,B,D,A,B>的子序列,相应的递增下标序列为<2, 3, 5, 7>。

PG13okc的博客 1万+

最长公共子序列问题(经典DP)

在两个字符串中,有些字符会一样,可以形成的子序列也有可能相等,因此,长度最长的相等子序列便是两者间的最长公共字序列,其长度可以使用动态规划来求。 以s1={1,3,4,5,6,7,7,8},s2={3,5,7,4,8,6,7,8,2}为例。 借用《算法导论》中的推导图: 创建 DP数组C[][]; 图中的空白格子需要填上相应的数字(这个数字就是c[i][j]的定义,记录的LCS的...

WYwysun的博客 447

动态规划之【线性DP】第9课:最长公共子序列

动态规划之【线性DP】第9课:最长公共子序列

王老师青少年编程 616

动态规划之【线性DP】第10课:最大子段和、最长上升子序列、最长公共子序列总结和对比

动态规划之【线性DP】第10课:最大子段和、最长上升子序列、最长公共子序列总结和对比

王老师青少年编程 875

动态规划篇——最长公共子序列(c++)

引言:最长公共子序列属于动态规划的基础篇,由字符串的最长公共最序列可以引出很多的问题。 最长子序列详细讲解以及练习题目 需要详细讲解教程的可以观看上面链接的文章,以下是自己做的简单的概括。 一、何为最长公共子序列 A和B的公共子序列中长度最长的(包含元素最多的)叫做A和B的公共子序列。 仍然用序列1,3,5,4,2,6,8,7和序列1,4,8,6,7,5 它们的最长公共子序列是: 1,4,8,7...

qq_43353709的博客 1万+

解决用VScode写中文注释,Vivado打开之后是乱码的方法

这样就解决了中文注释乱码的问题,此外如果使用notepad++写verilog代码的话直接在notepad++上面将编码格式改为ANSI格式即可,更加方便快捷,所以此方法仅针对习惯用VScode写Verilog的同学,如果有其他好办法的话欢迎评论区补充。首先,VScode中的中文默认编码格式是UTF-8,然后Vivado的编码格式是vivado 默认的应该是ANSI编码格式,刚开始我先按照网上说明的,将VScode中的编码格式改为GBK格式(点击右下角->点击通过编码保存)。

weixin_50573305的博客 5813

LCS(最长公共子序列)和dp(动态规划)

参照:v_JULY_v        最长公共子序列定义:         注意最长公共子串(Longest CommonSubstring)和最长公共子序列(LongestCommon Subsequence, LCS)的区别:子串(Substring)是串的一个连续的部分,子序列(Subsequence)则是从不改变序列的顺序,而从序列中去掉任意的元素而获得的新序列;更简略地说,前者(子串

寻找、发现、追求、获得———这就是狼的生活要素 3925

立创开源桌面激光雕刻机DIY全解析:从悬臂结构、Arduino主控到Marlin固件

本文详细解析了基于立创开源平台的桌面激光雕刻机DIY全过程。重点介绍了悬臂式机械结构的设计与优化,阐述了采用Arduino Mega 2560主控与RAMPS 1.4扩展板的经典控制方案,并深入讲解了Marlin固件的关键配置步骤,包括电机步数计算与激光功能启用,为创客和电子爱好者提供了一套完整的从硬件搭建到软件调试的实战指南。

weixin_42510201的博客 385

Claude Code 接入 DeepSeek-V4 教程

本文介绍Claude Code的安装配置流程:1) 安装Node.js 18+和Git(Windows);2) 通过npm全局安装@anthropic-ai/claude-code;3) 配置DeepSeek API环境变量(需替换API Key);4) 启动Claude Code或配置VSCode插件。重点包括Linux/macOS和Windows的环境变量设置方法,以及VSCode插件的settings.json配置项。完成配置后即可在终端或VSCode中使用Claude Code功能。

培根芝士的专栏 2010

动态规划(DP)---- 最长公共子序列

首先咱们定义dp数组的含义,这里所求的为最长公共子序列的长度,那么咱们不妨给dp数组定义为最长公共子序列,那么分析维数,这里所要的是两个子序列,假设这两个子序列的长度分别为m和n,所以。当i ≠ j时,代表两个子串的第i个和第j个是不一样的,所以咱们这里要找出最大的那一个作为当前遍历的值所对应的最长公共子序列,所以其状态方程为。定义完dp数组的含义,我们就要找到其状态方程,首先分析dp数组的含义,我们分析题干,这里通过递推dp数组来推出值,也就是。

记得开心一点嘛的博客 831

SPAD单光子雪崩二极管:从基础原理到前沿应用

本文深入解析SPAD单光子雪崩二极管的基础原理、硬件实现关键及核心性能参数,并探讨其在激光雷达、量子通信和生物医学成像等前沿领域的创新应用。SPAD凭借超高灵敏度和精确的时间分辨率,正在推动自动驾驶、量子技术和医学诊断等领域的革命性发展。

weixin_30335575的博客 663

算法竞赛备赛——【动态规划DP】最长公共子序列LCS

在求解LCS时,一般设dp[i][j]表示A[1~i]序列和B[1~j]序列中的最长公共子序列的长度(不规定结尾),状态转移方程为此方法的时间复杂度为:O(n^2)

2302_79975436的博客 415

实战解析:利用Wireshark解密QQ通信协议

本文提供了一份利用Wireshark工具分析QQ通信协议的实战指南。文章详细介绍了从环境准备、捕获数据包到解析协议层的完整流程,重点演示了如何识别QQ号码字段、观察加密数据特征以及区分不同通信类型(如文本、文件传输)。通过此实践,读者可以深入理解网络分层模型和现代应用加密通信机制,提升网络协议分析与安全诊断能力。

weixin_29210727的博客 408

导出库的版本_Windows下PaddleOCR在C++中的推理部署(CPU版本)CMake + VS2017

PaddleOCR是一个与OCR相关的开源项目,不仅支持超轻量级中文OCR预测模型,总模型仅8.6M(单模型支持中英文数字组合识别、竖排文本识别、长文本识别,其中检测模型DB(4.1M)+识别模型CRNN(4.5M)),而且提供多种文本检测训练算法(EAST、DB)和多种文本识别训练算法(Rosetta、CRNN、STAR-Net、RARE)。本文将教大家通过PaddleOCR(CPU版...

weixin_31304817的博客 1914

Day47 | 动态规划 :线性DP 最长公共子序列&&最长公共子数组

本次题解参考自灵神的做法,大家也多多支持灵神的题解1.思考回溯法(深度优先遍历)怎么写注意要画树形结构图2.转成记忆化搜索看哪些地方是重复计算的,怎么用记忆化搜索给顶替掉这些重复计算3.把记忆化搜索翻译成动态规划基本就是1:1转换。

m0_74795952的博客 877

eNSP与我这24H2版本不兼容,路由器40错误。这该怎么处理(操作系统-windows)(相关搜索:虚拟机)

🏆本文收录于《全栈Bug调优(实战版)》专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!

**My Coding Family** 4110

【动态规划:两个数组的dp问题】最长公共子序列 && 不相交的线

本文介绍了最长公共子序列(LCS)问题的动态规划解法模板,并延伸至不相交的线问题。对于LCS问题,通过构建二维DP表,状态定义为dp[i][j]表示text1[0..i]和text2[0..j]的最长公共子序列长度。通过分情况讨论末尾字符是否相等,填充DP表。不相交的线问题本质与LCS相同,只需将数组元素匹配转化为连线条件。两题均采用虚拟行列优化初始化,时间复杂度为O(nm)。代码实现简洁,关键点在于状态转移方程和边界处理。

lirendada的博客 1180

openCv +3.4.0 车牌定位(C++版本)

#include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc.hpp> #include "opencv2/shape.hpp" using namespace ...

Bamboo265925的博客 2337

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

以最长公共子序列问题理解动态规划算法(DP)

一、动态规划(Dynamic Programming) 动态规划方法通常用于求解最优化问题。我们希望找到一个解使其取得最优值,而不是所有最优解,可能有多个解都达到最优值。 二、什么问题适合DP解法 如何判断一个问题是不是DP问题呢?适合DP求解的最优化问题通常具有以下两个特征: 最优子结构 如果一个问题的最优解包含其子问题的最优解,我们就称此问题具有最优子结构性质。 以0-1背包问题(给你一个可装载重量为W的背包和N个物品,每个物品有重量和价值两个属性。其中第i个物品的重量为wt[i],

m0_50180963的博客 651

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

(LeetCode 动态规划(基础版))1143. 最长公共子序列(动态规划dp)

【代码】(LeetCode 动态规划(基础版))1143. 最长公共子序列(动态规划dp)

记录一些刷过的题并分享学习心得 553

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【牛客网动态规划专项】DP19 最长公共子序列(一)

的含义为:s1从头到下标i的子字符串(s1[0…i]) 与 s1从头到下标j的子字符串(s2[0…j]) 的最长公共子序列的长度。

weixin_42904738的博客 167

(LeetCode 热题 100) 1143. 最长公共子序列(动态规划dp)

【代码】(LeetCode 热题 100) 1143. 最长公共子序列(动态规划dp)

记录一些刷过的题并分享学习心得 427

夕拾算法进阶篇:15)最长公共子序列(动态规划DP)

题目描述 给你一个序列X和另一个序列Z,当Z中的所有元素都在X中存在,并且在X中的下标顺序是严格递增的,那么就把Z叫做X的子序列。 例如:Z=是序列X=的一个子序列,Z中的元素在X中的下标序列为。 现给你两个序列X和Y,请问它们的最长公共子序列的长度是多少? 输入 输入包含多组测试数据。每组输入占一行,为两个字符串,由若干个空格分隔。每个字符串的长度不超过100。

Javis486的专栏 729

最长公共子序列(DP,动态规划)

最长公共子序列 题目描述 给你一个序列X和另一个序列Z,当Z中的所有元素都在X中存在,并且在X中的下标顺序是严格递增的,那么就把Z叫做X的子序列。 例如:Z=<a,b,f,c>是序列X=<a,b,c,f,b,c>的一个子序列,Z中的元素在X中的下标序列为<1,2,4,6>。 现给你两个序列X和Y,请问它们的最长公共子序列的长度是多少? 输入 输入包含多组测试数据。每组输入占一行,为两个字符串,由若干个空格分隔。每个字符串的长度不超过100。 输出 对于每组输入,输出两个字

准备23考研。不定期更新考研知识 235
上一篇: 简易版扑克牌程序
下一篇: 回溯之N皇后问题
Python_programer
博客等级 码龄9年 25粉丝 57原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值