C++动态规划解决最长公共子序列

动规非常经典的一道题目,由于需要用到二维数组——姑且算为中等难度的题目,其实和01背包有着极高的相似度,无论是实现还是理论。

今天这篇博客不讲过多的DP理论,重在讲解题目本身。其实有一定经验的同志都清楚,DP的难点在于想明白子问题分割的细节——也即列出正确的状态转移方程,只要方程正确,那么无论是用C++、Java甚至MATLAB,实现起来都很简单。

再来介绍题目本身,和最长公共子串不同的是——公共子序列中的元素可以是不连续的,但对于子串则必须连续。举个简单的例子:

对于ABBCC和ABCDE来说:

  • 最长公共子序列可以不连续,因此是ABC
  • 最长子串必须连续,因此是AB

一.子问题的划分

还是举上面的例子,对于这两个长度为5的子串,如果我们要得到他们之间的最长公共子序列,肯定要先知道其中一个减去一位后最长的子序列作为先导,又要以两者均减去一位后得到的最长子序列。

 以此类推,实际上我们最终可以将子问题分解为只有0个字母时——两者的公共子序列。我们将这个状态也即子问题记为answer(X,Y),即最小子问题为(0,0),在编码中我们用二维数组DP表示,如下图:横纵两轴分别表示在目标子串之一包含该字母的情况下,二者的最长公共子序列~

二.初始化DP数组

这也是动态规划里面的一大基本操作,我们要人为地给出问题的初试解。在本题目中,当一个子串为长度为0时,另一个无论多长,二者的公共长度均为0,因此作出如下初始化:

实际上,任何需要用到二维数组的题目——比如01背包, 横纵轴分别表示物品序号和当前背包重量,都是这样初始化DP数组的。

三.列出状态转移方程

我们先来看一个简单的情况:也即子问题(1,1)——两个序列均有一个字母的时候,由于用例二者头字母均为A,因此在当前情况下最长公共子序列长度为1。

继续观察一下:假如现在第一个串多了一位,而第二个不变,也即子问题(2,1)——由于我们要求的是公共的最大子序列,现在一个人多了一位,另一个不变——换句话说其实和这个人多了一位后对答案毫无影响!因此我们的(2,1)应该怎么填呢?是不是还是1!以此类推,(1,2)的答案也是1:

前面说到,单独一个加一位 不影响什么结果,那如果两个人同时加呢?设想一下,比如我们先从(1,1)的基础上加一位变成(2,1),此时我们要计算(2,2),相当于第二个序列的扩充可能会带来一位的增加,因此我们的(2,2)必然是大于等于(2,1)的——即扩充长度是一个单调不减的过程。但实际上我们还得考虑(1,2)的情况,也即这两种都有可能因为扩充其中的一位,导致answer加一!所以我们的(2,2)应该是两者之中更大的一位!

最终结果如下图所示:红色的色块表示当前两个字符串中有新的一样的子列添加进来,因此需要加一。如果不相同就从上方和左边选一个最大的即可~
 

我们来编码实现一下:

#include <iostream>
#include <string> 
using namespace std;
int main()
{string s1,s2;cin>>s1;cin>>s2;int n1=s1.length(),n2=s2.length();int DP[n1+1][n2+1];//n1行,n2列,也即纵向为第一个字符串 for(int i=0;i<=n2;i++){for(int j=0;j<=n1;j++)DP[i][j]=0;//数据预处理,脏数据经常出现~ }for(int i=1;i<=n2;i++){for(int j=1;j<=n1;j++) {if(s1[j-1]==s2[i-1])//相等则从上个对角元素+1 DP[i][j]=DP[i-1][j-1]+1;elseDP[i][j]=max(DP[i-1][j],DP[i][j-1]);//不相等则从只增加其中一位后的情况中选一个大的 }}for(int i=0;i<=n2;i++){for(int j=0;j<=n1;j++)cout<<DP[i][j]<<" ";cout<<endl;}return 0;
}

没什么问题:

数组的最右下角即为最长公共子序列的长度~

 

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

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

相关文章

学习日志024--opencv中处理轮廓的函数

目录 前言​​​​​​​ 一、 梯度处理的sobel算子函数 功能 参数 返回值 代码演示 二、梯度处理拉普拉斯算子 功能 参数 返回值 代码演示 三、Canny算子 功能 参数 返回值 代码演示 四、findContours函数与drawContours函数 功能 参数 返回值 代码演示 …

《Modern CMake for C++》学习笔记

学习 Modern CMake for C - Second Edition 时的学习笔记&#xff0c;供大家参考。 相关资源&#xff1a; 原书链接&#xff1a; Modern CMake for C: Effortlessly build cutting-edge C code and deliver high-quality solutions , Second Edition 中文翻译链接&#xff1a…

实战 | 某院校小程序记录

更多大厂面试经验的视频分享看主页和专栏 目录&#xff1a; 前言&#xff1a; 渗透思路 1.绕过前端 2.信息泄露 3.爆破用户账号密码 4.信息泄露2 结束 前言&#xff1a; 遇到一个学校小程序的站点&#xff0c;只在前端登录口做了校验&#xff0c;后端没有任何校验&#x…

Visual studio的AI插件-通义灵码

通义灵码 TONGYI Lingma 兼容 Visual Studio、Visual Studio Code、JetBrains IDEs 等主流 IDE&#xff1b;支持 Java、Python、Go、C/C、C#、JavaScript、TypeScript、PHP、Ruby、Rust、Scala 等主流编程语言。 安装 打开扩展管理器&#xff0c;搜送“TONGYI Lingma”&…

【泛微系统】HR同步功能实例讲解

HR同步功能实例讲解\ 前言 HR同步是指ecology与专业的人事管理软件进行数据同步的功能,ecology中的组织结构和人员信息将完全取自HR软件。 官方HR同步功能解释 实例背景 客户本身有外购EHR系统用于员工的入转调离的基础信息管理,现又外购泛微的OA系统用于企业信息协同办…

【测试】Pytest

建议关注、收藏&#xff01; 目录 功能pytest 自动化测试工具。 功能 单元测试&#xff1a;用于验证代码的最小功能单元&#xff08;如函数、方法&#xff09;的正确性。 简单的语法&#xff1a;不需要继承特定类或使用复杂的结构。断言语句简化。 自动发现测试&#xff1a;P…

实验12 socket网络编程

设计程序 1&#xff0e;阅读TCP、UDP数据通信的例子8-2、8-7&#xff0c;理解并运行查看其功能。 2. 编写程序&#xff0c;使用socket网络接口函数&#xff0c;实现同一网段的两台主机的聊天。注&#xff1a;使用多线程&#xff0c;实现实时聊天功能。&#xff08;使用UDP或TCP…

【LeetCode】2406、将区间分为最少组数

【LeetCode】2406、将区间分为最少组数 文章目录 一、数据结构-堆、贪心1.1 数据结构-堆、贪心1.2 多语言解法 二、扫描线2.1 扫描线 一、数据结构-堆、贪心 1.1 数据结构-堆、贪心 题目已知一些区间, 需要尽量合并, 使 组 最少. 可以用图解画一下 因为尽量合并, 为了紧凑, …

【Python】利用函数模拟创建【栈】的数据结构操作

知识解读&#xff1a;来自&#xff1a;https://fishc.com.cn[#FwSB,M 9xKOA!^6fP)_EC(nsd什么是栈呢&#xff1f;Powered by https://fishc.com.cn3>A?5JXL#_}YBGD"FWdubKeyhQP栈是一种具有 FILO 特性的数据结构&#xff0c;即先放入的数据反而后取出。e&"%b…

JAVA入门:使用IDE开发

JAVA入门:使用IDE开发 什么是IDE IDE(Integrated Development Environment,集成开发环境)是一种软件应用程序,它为程序开发、软件设计、项目管理等提供全面的设施。 简单来说就是简化开发过程,让编程更加方便。 IDEA 业界公认最好用的JAVA IDE 安装IDEA 打开IDEA官…

机器学习《西瓜书》学习笔记《待续》

如果说&#xff0c;计算机科学是研究关于“算法”的学问&#xff0c;那么机器学习就是研究关于“学习算法”的学问。 目录 绪论引言基本术语 扩展向量的张成-span使用Markdown语法编写数学公式希腊字母的LaTex语法插入一些数学的结构插入定界符插入一些可变大小的符号插入一些函…

o1 Pro模型架构揭秘与 Scaling Law 深度解析 | Claude 3.5 Opus、草莓训练、推理成本剖析

引言 近期&#xff0c;Semianalysis 发布了一篇重磅万字长文&#xff0c;首次披露 OpenAI 的 o1 Pro 模型架构与推理训练方法&#xff0c;同时深入探讨了当前 AI 领域的重要话题&#xff1a; Claude 3.5 Opus 是否失败&#xff1f;Scaling Laws&#xff08;扩展法则&#xff…

流程引擎Activiti性能优化方案

流程引擎Activiti性能优化方案 Activiti工作流引擎架构概述 Activiti工作流引擎架构大致分为6层。从上到下依次为工作流引擎层、部署层、业务接口层、命令拦截层、命令层和行为层。 基于关系型数据库层面优化 MySQL建表语句优化 Activiti在MySQL中创建默认字符集为utf8&…

labml.ai Deep Learning Paper Implementations (带注释的 PyTorch 版论文实现)

labml.ai Deep Learning Paper Implementations {带注释的 PyTorch 版论文实现} 1. labml.ai2. labml.ai Deep Learning Paper Implementations3. Sampling Techniques for Language Models (语言模型的采样技术)4. Multi-Headed Attention (MHA)References 1. labml.ai https…

qemu源码解析【04】qom实例

目录 qemu源码解析【04】qom实例1. type_init()宏2. type_register_static()宏3. arm_sbcon_i2c_init()何时被qemu系统调用 qemu源码解析【04】qom实例 qemu源码解析【总目录】 继续分析arm_sbcon_i2c实例&#xff0c;代码从行尾往上逐步分析 #include "qemu/osdep.h&q…

【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题

目录 背包问题简介 问题描述 输入&#xff1a; 输出&#xff1a; 动态规划解法 动态规划状态转移 代码实现 代码解释 动态规划的时间复杂度 例子解析 输出&#xff1a; 总结 作者我蓝桥杯&#xff1a;2023第十四届蓝桥杯国赛C/C大学B组一等奖&#xff0c;所以请听我…

【C++】抽象之神:类和对象(中)万字详解

Hi&#xff0c;朋友们&#xff0c;好久不见 我们上次学到了C类和对象&#xff08;上&#xff09;&#xff0c;感觉那难度还行&#xff0c;能接受&#xff0c;但这次的类和对象&#xff08;中&#xff09;&#xff0c;一开始真是让我觉得脑子转不动的无力感&#xff0c;难呐&am…

C++手动实现一个HashMap

1.HashMap原理 参考我的博客&#xff1a;https://blog.csdn.net/Revendell/article/details/110009858 开链法&#xff1a;STL的hashtable便是采用开链法解决冲突。这种做法是在每一个表格元素中维护一个list&#xff1a;散列函数为我们分配某一个list&#xff0c;然后我们在…

【Linux】深入理解进程信号机制:信号的产生、捕获与阻塞

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 时间不语&#xff0c;却回答了所有问题 目录 &#x1f4da;前言 &#x1f4da;一、信号的本质 &#x1f4d6;1.异步通信 &#x1f4d6;2.信…

sql server 数据库还原,和数据检查

右键数据库选择还原&#xff0c; 还原的备份文件必须选择在本地的文件&#xff08;远程文件没有试过&#xff09;还原数据库名字可以修改&#xff0c;然后file选择中有个2个目录data file 的目录 &#xff0c;和log data 的目录都可以重新选择还原到的新的目录&#xff0c;不要…