洛谷P1439 【模板】最长公共子序列
一 题意
给出两个序列,求在这两个序列中的最长公共子序列的长度 题目出门右转
二 思路
将一个序列作为标准序列,即在它里面元素的大小关系是等价于它的排列顺序
序列1 1 3 10 8 5
序列2 10 3 1 8 5
以序列一为标准得到的元素大小关系
元素 | 1 | 3 | 10 | 8 | 5 |
---|---|---|---|---|---|
大小 | 1 | 2 | 3 | 4 | 5 |
以这样的大小关系带入到序列2中去
元素 | 10 | 3 | 1 | 8 | 5 |
---|---|---|---|---|---|
大小 | 3 | 2 | 1 | 4 | 5 |
那么此时要求最长公共子序列就成了求序列2的最长递增子序列
三 代码
#include <iostream>
#include <algorithm>
using namespace std;
int p1[100010];
int p[100010];
int p2[100010];
int f[100010];
int low[100010];
int n;
int main() {
scanf("%d",&n);
for (int i=1; i<=n; i++) {scanf("%d",&p1[i]);p[p1[i]]=i;}
// 得到序列1的编号
for (int i=1; i<=n; i++) scanf("%d",&p2[i]);
for (int i=1; i<=n; i++) {f[i]=p[p2[i]];low[i]=999999999;}
// 以序列2的大小序对序列一进行排序
low[1]=f[1];
int len=1;
// LIS标准解法
for (int i=2; i<=n; i++) {
if(f[i]>=low[len])
{
len++;
low[len]=f[i];
}
else low[lower_bound(low+1, low+len+1, f[i])-low]=f[i];
}
printf("%d",len);
return 0;
}