P1439「【模板】最长公共子序列」
1. 题目
题目链接:P1439「【模板】最长公共子序列」 。
题目描述
给出 的两个排列 和 ,求它们的最长公共子序列。
输入格式
第一行是一个数 。
接下来两行,每行为 个数,为自然数 的一个排列。
输出格式
一个数,即最长公共子序列的长度。
输入输出样例
输入 #1
1 |
|
输出 #1
1 |
|
说明/提示
-
对于 的数据,;
-
对于 的数据,。
2. 题解
分析
这是一道 LCS 的模板题,但是如果只用朴素的动态规划来解,复杂度是 ,结果终究会 TLE。和 LCS 类似的是 LIS,然而 LIS 有 的解法,幸运的是部分 LCS 问题可以用 LIS 来解。
-
在 LCS 中,两个序列中的元素仅表示一种符号,用来判定是否相等的符号,对于符号背后具体的数值对 LCS 的结果并没有影响。
-
在 LIS 中,是需要考虑序列元素的数值大小关系的。
若 LCS 的两个序列中的其中一个元素互异,则可以用 LIS 来解。在此类 LCS 中,不防假设序列 中元素是互异的,设序列 的长度为 ,则我们可以考虑将 的元素按照出现顺序依次映射到 上,从而得到 中元素与数值的一一对应关系。然后根据 元素的映射表,来计算序列 元素对应的映射值;对于在 中存在而不在 中存在的元素,直接舍弃即可,因为它们必然不会出现在 LCS 中。如此,映射完 得到的数值序列设为 ,其长度为 。则此时只需要计算序列 的 LIS 即可。这是因为序列 映射后的序列是一个递增的数值序列,因此 和 的公共子序列也是递增子序列,最长公共子序列也是最长递增子序列,即序列 的最长递增子序列。
针对这道题而言,由于两个序列都是 的排列,因此可以转为 LIS 问题来求解。
代码
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!