首页 > 其他分享 >最长公共子序列

最长公共子序列

时间:2023-08-10 17:35:14浏览次数:30  
标签:mid len 公共 序列 最长 dp

最长公共子序列

一、什么是最长公共子序列(Longest Common Subsequence, LCS)?

最长公共子序列(LCS)是指在两个序列中,找出一个最长的子序列,使得这个子序列在这两个序列中都出现过。换句话说,就是从两个序列中删除一些元素后,剩下的最长公共子序列的长度。

二、原理

我们可以使用动态规划的方法来解决这个问题。首先,我们需要定义一个二维数组dp,其中dp[i][j]表示序列1的前i个元素和序列2的前j个元素的最长公共子序列的长度。接下来,我们可以通过以下步骤计算dp数组:

  1. 初始化dp数组的第一行和第一列为0。

  2. 从第二行第二列开始遍历dp数组,对于每个位置(i, j),如果序列1的第i个元素等于序列2的第j个元素,那么

    \[dp[i][j] = dp[i-1][j-1] + 1 \]

    否则,

    \[dp[i][j] = max(dp[i-1][j], dp[i][j-1]) \]

  3. 最后,dp[m][n]就是我们要求的最长公共子序列的长度,其中mn分别是序列1和序列2的长度。

三、C++代码实现

#include<bits/stdc++.h>
#define reg register
using namespace std;

// 定义一个函数read,用于读取输入的整数并返回
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1; // 如果输入的是负号,则将f设为-1
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48); // 将输入的数字转换为二进制表示,并存储在x中
		ch=getchar();
	}
	return x*f; // 返回读取的整数
}

// 定义一个函数write,用于输出整数x并在前面添加负号(如果x为负数)
void write(int x){
	if(x<0){
		putchar('-'); // 如果x为负数,先输出负号
		x=-x; // 将x变为正数
	}
	if(x>9) write(x/10); // 如果x大于9,递归调用write函数输出十位数
	putchar(x%10+'0'); // 输出个位数
	return ;
}

const int MAXN=100005,INF=0x7fffffff; // 定义常量MAXN为100005
int n,mapp[MAXN],dp[MAXN]; // 定义变量n、mapp[]、dp[]
vector<int > a,b; // 定义向量a、b

int main(){
	n=read(); // 从输入中读取整数n,存入变量n中
	a.push_back(0),b.push_back(0); // 在向量a和b的末尾分别添加元素0
	for(reg int i=1;i<=n;i++){a.push_back(read());mapp[a[i]]=i;} // 从输入中读取n个整数,存入向量a中,并将每个元素在向量a中的下标存入数组mapp中对应的位置
	for(reg int i=1;i<=n;i++){b.push_back(read());dp[i]=INF;} // 从输入中读取n个整数,存入向量b中,并将每个元素在dp[]中的值初始化为最大值
	for(reg int i=1;i<=n;i++) b[i]=mapp[b[i]]; // 将向量b中的每个元素替换为其在数组mapp中的下标所对应的值
	dp[1]=b[1]; // 将dp[1]设置为b[1]的值
	int len=1; // 将len设置为1
	for(reg int i=2;i<=n;i++){ // 从第2个元素开始遍历向量b和dp[]
		int l=0,r=len,mid; // 将l、r、mid分别初始化为0、len、len/2的商
		if(b[i]>dp[len]) dp[++len]=b[i]; // 如果b[i]大于dp[len],则将dp[len]更新为b[i]的值,并将len加1
		else{
			while(l<r){ // 当l小于r时,执行循环体
				mid=(l+r)>>1; // 将mid设置为l和r的平均值
				if(dp[mid]>b[i]) r=mid; // 如果dp[mid]大于b[i],则将r更新为mid的值
				else l=mid+1; // 否则将l更新为mid+1的值
			}
			dp[l]=min(b[i],dp[l]); // 将dp[l]更新为b[i]和dp[l]中的较小值
		}
	}
	write(len); // 将len写入输出流
	return 0; // 程序正常结束,返回0
}

四、例题及题解

题目:给定两个字符串序列 s1s2,请编写一个函数 longestCommonSubsequenceLength,返回它们的最长公共子序列的长度。你只能使用一次回溯法。

解题思路:
由于题目要求只使用一次回溯法,我们可以先找到两个字符串的最长公共子序列,然后再根据最长公共子序列构造出原问题中的字符串。这样就可以避免使用递归。具体实现可以参考上面的 C++ 代码。

标签:mid,len,公共,序列,最长,dp
From: https://www.cnblogs.com/Nebulary/p/17620971.html

相关文章

  • springboot~alibaba.fastjson2序列化时过滤字段
    当我们使用阿里的alibaba.fastjson2进行json序列化时,你可以通过方法参数PropertyFilter来实现对字段的获取,将需要序列化的字段写到PropertyFilter对象里,当然也可以将不进行序列化的写到这里,进行逻辑非操作即可实体classPerson{privateStringfirstName;privateStr......
  • MATLAB用深度学习长短期记忆 (LSTM) 神经网络对智能手机传感器时间序列数据进行分类|
    原文链接:http://tecdat.cn/?p=26318原文出处:拓端数据部落公众号 最近我们被客户要求撰写关于长短期记忆(LSTM)神经网络的研究报告,包括一些图形和统计输出。此示例说明如何使用长短期记忆(LSTM)网络对序列数据的每个时间步长进行分类。要训​​练深度神经网络对序列数据......
  • 子序列的最大优雅度
    给你一个长度为n的二维整数数组items和一个整数k。items[i]=[profiti,categoryi],其中profiti和categoryi分别表示第i个项目的利润和类别现定义items的子序列的优雅度可以用total_profit+distinct_categories2计算从items所有长度为k的子序列中,找出......
  • 序列学习
    序列学习生活中的所有事物都是与时间相关的,也就形成了一个序列。为了对序列数据(文本、演讲、视频等)我们可以使用神经网络并导入整个序列,但是这样我们的数据输入尺寸是固定的,局限性就很明显。如果重要的时序特征事件恰好落在输入窗以外,就会产生更大的问题。所以我们需要的是:......
  • Python用GARCH对ADBL股票价格时间序列趋势滚动预测、损失、可视化分析
    全文链接:https://tecdat.cn/?p=33398原文出处:拓端数据部落公众号金融市场的股票价格时间序列分析一直以来都是投资者和研究者关注的主题之一。准确预测股票价格的趋势对于制定有效的投资策略和决策具有重要意义。因此,许多研究人员使用各种统计方法和模型来分析和预测股票价格的......
  • 序列化
    什么是序列化我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。为什么要序列化1.持久保存状态需知一个软件/程序的执行就在处理一系列状态的变化,在编程语言中,'状......
  • delphi 自带的JSON序列化类
    unitUnit1;interfaceusesWinapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,System.JSON.Serializers,Vcl.StdCtrls;typeTForm1=class(TForm)Memo1:TMemo......
  • Weblogic WLS Core Components 反序列化命令执行漏洞(CVE-2018-2628)
    Vulhub-Docker-Composefileforvulnerabilityenvironment1、介绍名称:WeblogicWLSCoreComponents反序列化命令执行漏洞(CVE-2018-2628)编号:CVE-2018-2628原理:应用:Weblogic 版本:Weblogic10.3.6.0,Weblogic12.1.3.0,Weblogic12.2.1.2,Weblogic12.2.1.32、测试2.......
  • Atcoder ABC307_G-Approximate Equalization 序列dp
    AT_ABC307_G-ApproximateEqualization没想到还有ApproximateEqualizationII!!:AT_ABC313_CDescription:给定一个长度为\(N\)的数列:\(A=(A_1,A_2,···,A_N)\),有两种操作可以以任意顺序进行任意多次(可以为0):\(A[i]-\)=\(1\)且\(A[i+1]+\)=\(1\),\((1\leqi\leqN-1)......
  • 最长回文串
    给定一个包含大写字母和小写字母的字符串s,返回通过这些字母构造成的最长的回文串。在构造过程中,请注意区分大小写。比如"Aa"不能当做一个回文字符串。示例1:输入:s="abccccdd"输出:7解释:我们可以构造的最长的回文串是"dccaccd",它的长度是7。示例2:输入:s......