Coincidence (九度教程第98题) 最长公共子序列(LCS) 动态规划

2023-10-17 09:38

本文主要是介绍Coincidence (九度教程第98题) 最长公共子序列(LCS) 动态规划,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Find a longest common subsequence of two strings.
输入描述:
First and second line of each input case contain two strings of lowercase character a…z. There are no spaces before, inside or after the strings. Lengths of strings do not exceed 100.
输出描述:
For each case, output k – the length of a longest common subsequence in one line.
示例1
输入
abcd
cxbydz
输出
2

题目大意:
求出两个字符串的最长公共子串长度,典型的最长公共子序列问题。
解题思路:动态规划

与求最长递增子序列一样,我们首先将原问题分割成一些子问题,我们用
dp[ i ][ j ]表示 S1 中前 i 个字符与 S2 中前 j 个字符分别组成的两个前缀字符串的最
长公共子串长度
。显然的,当 i、j 较小时我们可以直接得出答案,如 dp[ 0 ][ j ]必
等于 0。那么,假设我们已经求得 dp[ i ][ j ](0<=i<x || 0<=j<y)的所有值,考虑如何由
这些值继而推得 dp[x][y],求得 S1 前 x 个字符组成的前缀子串和 S2 前 y 个字符
组成的前缀子串的最长公共子序列长度。
若 S1[x] = =S2[y],即 S1 中的第 x 个字符和 S2 中的第 y 个字符相同,同时由于他们都是各自前缀子串的最后一个字符,那么必存在一个最长公共子串以 S1[x]或 S2[y]结尾,其它部分等价于 S1 中前 x-1个字符和S2中前y-1个字符的最长公共子串。所以这个子串的长度比dp[x-1][y-1]又增加 1,即 dp[x][y] = dp[x-1][y-1] + 1。
相反的,若 S1[x] != S2[y],此时其最长公共子串长度为 S1 中前 x-1 个字符和 S2 中前 y 个字符的最长公共子串长度与S1 中前 x 个字符和 S2 中前 y-1 个字符的最长公共子串长度的较大者,即在两种情况下得到的最长公共子串都不会因为其中一个字符串又增加了一个字符长度发生改变。综上所述,dp[x][y] = max{dp[x-1][y],dp[x][y-1]}。

综上所述,最长公共子序列问题的递推条件:

//字符串s1长度为n, 字符串s2长度为m
//dp[i][j]表示s1中前i个字符与s2中前j个字符分别组成的两个前缀字符串的最长公共子串长度
//dp[0][j]=0    0<=j<=m
//dp[i][0]=0    0<=i<=n
//dp[n][m]中保存的值即为两个原始字符串的最长公共子序列长度
if(s1[i]==s2[j]){ dp[i][j] = dp[i-1][j-1] + 1;}
else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);

AC代码

//最长公共子序列问题
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;int dp[101][101];
char s1[101], s2[101];
int main() {cin >> s1;cin >> s2;int a = strlen(s1);int b = strlen(s2);for (int i = 0; i <= a; i++) { dp[i][0] = 0; }for (int i = 0; i <= b; i++) { dp[0][i] = 0; }for (int i = 1; i <= a; i++) {for (int j = 1; j <= b; j++) {if (s1[i-1] == s2[j-1]) dp[i][j] = dp[i - 1][j - 1] + 1;else dp[i][j] = max( dp[i][j - 1], dp[i - 1][j] );}}cout << dp[a][b] << endl;//system("pause");return 0;
}

这篇关于Coincidence (九度教程第98题) 最长公共子序列(LCS) 动态规划的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/224515

相关文章

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

springboot简单集成Security配置的教程

《springboot简单集成Security配置的教程》:本文主要介绍springboot简单集成Security配置的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录集成Security安全框架引入依赖编写配置类WebSecurityConfig(自定义资源权限规则

MySQL Workbench 安装教程(保姆级)

《MySQLWorkbench安装教程(保姆级)》MySQLWorkbench是一款强大的数据库设计和管理工具,本文主要介绍了MySQLWorkbench安装教程,文中通过图文介绍的非常详细,对大... 目录前言:详细步骤:一、检查安装的数据库版本二、在官网下载对应的mysql Workbench版本,要是

通过Docker Compose部署MySQL的详细教程

《通过DockerCompose部署MySQL的详细教程》DockerCompose作为Docker官方的容器编排工具,为MySQL数据库部署带来了显著优势,下面小编就来为大家详细介绍一... 目录一、docker Compose 部署 mysql 的优势二、环境准备与基础配置2.1 项目目录结构2.2 基