あいさか たいがblogAisaka_Taiga的博客
//https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190806114008215-138720377.jpg

浅谈最长公共子序列

Toretto·2023-09-11 17:20·20 次阅读

浅谈最长公共子序列

最长公共子序列

定义#

最长公共子序列(LCS)是一个在一个序列集合中(通常为两个序列)用来查找所有序列中最长子序列的问题。
——维基百科

这里的子序列,是可以不连续的。

比如:

1 2 3 1 2 4 2

3 2 1 5 2 1 2

他们的最长公共子序列就是 2 1 2 2

也就是从两个序列,分别按顺序从左到右挑出一些元素形成两个新的序列使得两个序列相同,LCS 就是长度最大的那个。

LCS 不一定是唯一的。

求解#

模板题

考虑使用动态规划来解决问题。

我们设 f[i][j] 表示第一个序列前 i 个元素与第二个序列前 j 个元素的 LCS 长度。

那么我们就可以得到以下转移方程:

如果 a[i]=b[j] 的话:

f[i][j]=1+f[i][j]

如果 a[i]b[j] 的话:

f[i][j]=max(f[i1][j],f[i][j1])

时间空间复杂度都是 O(nm) 的。

于是得到以下的 code:

Copy
/* * @Author: Aisaka_Taiga * @Date: 2023-09-11 17:05:34 * @LastEditTime: 2023-09-11 17:09:52 * @LastEditors: Aisaka_Taiga * @FilePath: \Desktop\P439.cpp * 心比天高,命比纸薄。 */ #include <bits/stdc++.h> #define int long long #define N 5010 using namespace std; int n, f[N][N], a[N], b[N], ans; signed main() { cin >> n; for(int i = 1; i <= n; i ++) cin >> a[i]; for(int i = 1; i <= n; i ++) cin >> b[i]; for(int i = 1; i <= n; i ++) { for(int j = 1; j <= n; j ++) { if(a[i] == b[j]) f[i][j] = 1 + f[i - 1][j - 1]; else f[i][j] = max(f[i - 1][j], f[i][j - 1]); ans = max(ans, f[i][j]); } } cout << ans << endl; return 0; }

这个代码太垃圾了所以模板题只有 50 分。

image

posted @   北烛青澜  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2022-09-11 Tarjan学习笔寄
点击右上角即可分享
微信分享提示
目录