7-10 最长公共子序列

目录

题目描述

输入格式:

输出格式:

输入样例:

输出样例:

解题思路:

 详细代码:


题目描述

给出 1~n 的两个排列 P1 和 P2,求它们的最长公共子序列。

n 在 5~1000 之间。

输入格式:

第一行是一个数 n

接下来两行,每行为 n 个数,为自然数 1~n 的一个排列(1~n 的排列每行的数据都是 1~n 之间的数,但顺序可能不同,比如 1~5 的排列可以是:1 2 3 4 5,也可以是 2 5 4 3 1)。

输出格式:

一个整数,即最长公共子序列的长度。
数据范围

对于 25% 的数据 n≤10

对于 50% 的数据 n≤500

对于 75% 的数据 n≤800
对于 100% 的数据 n≤1000

输入样例:

5 
3 2 1 4 5
1 2 3 4 5

输出样例:

3

解题思路:

本题为线性动态规划

存在两种情况

1、如果当前匹配的元素相等,则长度加一

2、如果不相等,两个元素必定有一个可以去除

详细代码:

#include <iostream>
using namespace std;
const int N=1010;
int n,m;
int sz1[N],sz2[N];
int dp[N][N];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>sz1[i];
	}
	for(int i=1;i<=n;i++){
		cin>>sz2[i];
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			dp[i][j]=max(dp[i-1][j],dp[i][j-1]);    //不同,认定为从缺少这两种元素的前一种情况而来
			if(sz1[i]==sz2[j])dp[i][j]=dp[i-1][j-1]+1;	//相同长度加一
		}
	}
	cout<<dp[n][n];
}
最长公共子序列(Longest Common Subsequence, LCS)问题是计算机科学中的一个经典问题,主要用于比较两个序列(如字符串、数组等)的相似度。最长公共子序列是指在两个序列中都出现的子序列中,长度最长的那个。 ### 问题描述 给定两个序列 `X = (x1, x2, ..., xm)` 和 `Y = (y1, y2, ..., yn)`,求它们的最长公共子序列的长度。 ### 解决方法 最长公共子序列问题可以通过动态规划来解决。定义 `dp[i][j]` 为序列 `X` 的前 `i` 个元素和序列 `Y` 的前 `j` 个元素的最长公共子序列的长度。 动态规划的递推公式如下: 1. 如果 `xi == yj`,则 `dp[i][j] = dp[i-1][j-1] + 1`。 2. 如果 `xi != yj`,则 `dp[i][j] = max(dp[i-1][j], dp[i][j-1])`。 ### 代码示例 ```python def longest_common_subsequence(X, Y): m, n = len(X), len(Y) dp = [[0] * (n + 1) for _ in range(m + 1)] for i in range(1, m + 1): for j in range(1, n + 1): if X[i-1] == Y[j-1]: dp[i][j] = dp[i-1][j-1] + 1 else: dp[i][j] = max(dp[i-1][j], dp[i][j-1]) return dp[m][n] # 示例 X = "ABCBDAB" Y = "BDCABC" print("最长公共子序列长度:", longest_common_subsequence(X, Y)) ``` ### 解释 1. 初始化一个二维数组 `dp`,大小为 `(m+1) x (n+1)`,其中 `m` 和 `n` 分别是序列 `X` 和 `Y` 的长度。 2. 遍历序列 `X` 和 `Y`,填充 `dp` 数组。 3. 最终 `dp[m][n]` 就是最长公共子序列的长度。 ### 时间复杂度 时间复杂度为 `O(mn)`,其中 `m` 和 `n` 分别是两个序列的长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星与星熙.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值