给出两个长度为 n n n 的整数序列,求它们的最长公共子序列( L C S LCS LCS)的长度,保证第一个序列中所有元素都不重复。
注意:
输入格式
第一行包含一个整数
n
n
n。
接下来两行,每行包含 n n n 个整数,表示一个整数序列。
输出格式
输出一个整数,表示最长公共子序列的长度。
数据范围
1
≤
n
≤
1
0
6
,
1≤n≤10^6,
1≤n≤106,
序列内元素取值范围
[
1
,
1
0
6
]
[1,10^6]
[1,106]。
输入样例1:
5
1 2 3 4 5
1 2 3 4 5
输出样例1:
5
输入样例2:
5
1 2 3 5 4
1 2 3 4 5
输出样例2:
4
思路:
由于
a
a
a 中元素是唯一的,所以
b
b
b 中与
a
a
a 中公共的元素
x
x
x 一定在
a
a
a 中对应唯一的位置,可以将
b
b
b 中元素在
a
a
a 中出现的位置 记录到
i
d
id
id 数组中(不存在的标记为 -1
),此时可以发现,求
a
、
b
a、b
a、b 数组的最长公共子序列就相当于求
i
d
id
id 数组的最长子序列。
#include
#include
using namespace std;
const int N = 1000010;
int n;
int id[N], q[N];
int main(){
memset(id, -1, sizeof id);
scanf("%d", &n);
int x;
for(int i = 0; i < n; i++){
scanf("%d", &x);
id[x] = i;
}
int tt = 0;
q[0] = -1;
int k;
for(int i = 0; i < n; i++){
scanf("%d", &x);
if(id[x] == -1) continue;
k = id[x];
int l = 0, r = tt;
while(l < r){
int mid = l + r + 1 >> 1;
if(q[mid] < k) l = mid;
else r = mid - 1;
}
q[r + 1] = k;
tt = max(tt, r + 1);
}
printf("%d\n", tt);
return 0;
}