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;
			else
				DP[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;
}

没什么问题:

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

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Meta升级Ray-Ban智能眼镜:新增实时AI对话与翻译功能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

visual studio添加滚动条预览

如何在vs中添加如图的滚动条呢&#xff1f; 打开VS 工具栏 选项 - 文本编辑器 - C/C - 滚动条 行为-使用缩略图 -- 确定

VUE利用一句话复刻实现变声功能

实现思路&#xff1a;利用语音听写实现语音输入---拿到文字后自动调用一句话复刻实现声音输出。最终效果是A输入语音能够转换成B的语音输出。 <template><div class"One-container"><div><hr/><!--发音音色列表展示--><el-row :gut…

Firefly: 大模型训练工具,命令行执行训练,没有界面

文章目录 GitHub地址参数说明训练命令 Firefly: 大模型训练工具&#xff0c;支持训练Qwen2.5、Qwen2、Yi1.5、Phi-3、Llama3、Gemma、MiniCPM、Yi、Deepseek、Orion、Xverse、Mixtral-8x7B、Zephyr、Mistral、Baichuan2、Llma2、Llama、Qwen、Baichuan、ChatGLM2、InternLM、Zi…

自动驾驶AVM环视算法--python版本的俯视碗型投影模式

c语言版本和算法原理的可以查看本人的其他文档。《自动驾驶AVM环视算法--3D碗型投影模式的exe测试工具》本文档进用于展示部分代码的视线&#xff0c;获取方式网盘自行获取&#xff08;非免费介意勿下载&#xff09;&#xff1a;链接: https://pan.baidu.com/s/1STjUd87_5wDk_C…

汽车供应链 “剧变”开始,“智能感知潜在龙头”诞生

智能汽车产业链“剧变”已经开启&#xff0c;智能感知软硬件能力的权重正在不断被放大。 比如满足高阶泊车的第二代AK2超声波传感器、满足人机共驾场景需求的电子外后视镜&#xff08;CMS&#xff09;、iTOF 3D成像视觉感知&#xff08;用于舱内监控&#xff09;等新产品&…

计算机网络——期末复习(2)1-3章考试重点

第一章 概述 1、发送时延&#xff0c;其中数据帧长度为数据块大小1B8位 2、传播时延 3、 第二章 物理层 1、奈氏准则&#xff1a;理想低通信道的最高码元传输速率2W&#xff0c;W为理想低通信道的频率带宽 2、香农公式&#xff1a;&#xff0c;C为信道的极限信息传输速率&…

C++算法第九天

本篇文章我们继续学习c算法 目录 第一题 题目链接 题目展示 代码原理 暴力解法 二分解法 代码编写 第二题 题目链接 题目展示 代码原理 代码编写 重点回顾 朴素二分 非朴素二分 重点一 重点二 重点三 第一题 题目链接 153. 寻找旋转排序数组中的最小值 - 力…

HarmonyOS 实时监听与获取 Wi-Fi 信息

文章目录 摘要项目功能概述代码模块详细说明创建 Wi-Fi 状态保存对象Wi-Fi 状态监听模块获取当前 Wi-Fi 信息整合主模块 运行效果展示性能分析总结 摘要 本文展示了如何使用 HarmonyOS 框架开发一个 Demo&#xff0c;用于监听手机的 Wi-Fi 状态变化并实时获取连接的 Wi-Fi 信息…

gpu硬件架构

1.简介 NVIDIA在视觉计算和人工智能&#xff08;AI&#xff09;领域处于领先地位&#xff1b;其旗舰GPU已成为解决包括高性能计算和人工智能在内的各个领域复杂计算挑战所不可或缺的。虽然它们的规格经常被讨论&#xff0c;但很难掌握各种组件的清晰完整的图景。 这些GPU的高性…

【Qt】显示类控件:QLabel、QLCDNumber、QProgressBar、QCalendarWidget

目录 QLabel QFrame 例子&#xff1a; textFormat pixmap、scaledContents alignment wordWrap、indent、margin buddy QLCDNumber 例子&#xff1a; QTimer QProgressBar 例子&#xff1a; QCalendarWidget 例子&#xff1a; QLabel 标签控件&#xff0c;用来显示…

0001.基于springmvc简易酒店管理系统后台

一.系统架构 springmvcjsplayuimysql 二.功能特性 简单易学习&#xff0c;虽然版本比较老但是部署方便&#xff0c;tomcat环境即可启用&#xff1b;代码简洁&#xff0c;前后端代码提供可统一学习&#xff1b;祝愿您能成尽快为一位合格的程序员&#xff0c;愿世界没有BUG; …

Wallpaper壁纸制作学习记录12

角色表 创建人偶变形动画的更高级方法可以使用角色表来完成。角色表要求您使用角色的切割版本&#xff0c;将您的角色分成不同肢体/部分。这允许创建更复杂、更准确的动画&#xff0c;因为部分可以自由移动和重叠&#xff0c;而不会使图像失真。使用操控变形不一定能获得良好的…

【Python项目】基于Django的语音和背景音乐分离系统

【Python项目】基于Django的语音和背景音乐分离系统 技术简介&#xff1a;采用Python技术、Django框架、B/S结构&#xff0c;MYSQL数据库等实现。 系统简介&#xff1a;系统完成在线的音频上传&#xff0c;并且通过计算机的神经网络算法来对系统中的背景音乐和人声进行分离操作…

负载均衡oj项目:介绍

目录 项目介绍 项目演示 项目介绍 负载均衡oj是一个基于bs模式的项目。 用户使用浏览器向oj模块提交代码&#xff0c;oj模块会在所有在线的后端主机中选择一个负载情况最低的主机&#xff0c;将用户的代码提交给该主机&#xff0c;该主机进行编译运行&#xff0c;将结果返回…

【鸿睿创智开发板试用】移植OpenCV 4到OpenHarmony 4.1

目录 目录 引言 编译系统镜像 (1) 下载代码后解压SDK (2) 下载docker镜像   (3) 编译OH 编译OpenCV 下载OpenCV源代码 构建编译配置文件 执行编译命令 安装库和头文件 测试 结语 引言 最近有个需求是在基于RK3568的OpenHarmony 4.1系统中使用OpenCV&#xff0c…

【HarmonyOS之旅】HarmonyOS开发基础知识(一)

目录 1 -> 应用基础知识 1.1 -> 用户应用程序 1.2 -> 用户应用程序包结构 1.3 -> Ability 1.4 -> 库文件 1.5 -> 资源文件 1.6 -> 配置文件 1.7 -> pack.info 1.8 -> HAR 2 -> 配置文件简介 2.1 -> 配置文件的组成 3 -> 配置文…

【机器人】Graspness 端到端抓取点估计 | 环境搭建 | 模型推理测试

在复杂场景中实现抓取检测&#xff0c;Graspness是一种端到端的方法&#xff1b; 输入点云数据&#xff0c;输出抓取角度、抓取深度、夹具宽度等信息。 开源地址&#xff1a;https://github.com/rhett-chen/graspness_implementation?tabreadme-ov-file 论文地址&#xff1…

B站bilibili视频转文字字幕下载方法

本文将讲述介绍一种使用本地工具如何快速的下载B站的字幕为本地文本文件的方法。 通常获取B站字幕需要在浏览器中安装第三方插件&#xff0c;通过插件获取字幕。随着大模型&#xff0c;生成式AI&#xff0c;ChatGPT的应用&#xff0c;B站也提供了AI小助手对视频的内容进行总结…

CSS3 实现火焰-小火苗效果

创建 CSS3 火焰效果可以通过组合 CSS 动画、伪元素 和 渐变 来实现。以下是一个简单的实现步骤&#xff0c;展示如何制作动态火焰效果 1. HTML 结构 我们只需要一个简单的 div 容器&#xff1a; <div class"fire"></div>2. CSS 实现 基础样式 使用 …