AcWing 3510- 最长公共子序列 - 贪心+二分优化
Posted Chivas_/Regal
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 3510- 最长公共子序列 - 贪心+二分优化相关的知识,希望对你有一定的参考价值。
LCS问题
题目:
思路:
LCS是个动态规划问题,但我们可以用DP的思想贪过去
因为a中每个数只出现过一次,所以在这道题里面,我们可以将问题转化为一个LIS问题
首先设置一个数组 i d [ ] id[] id[]用来存入a数组里面的每个出现的数的下标
然后将b数组转化为b’数组,即 b ′ [ i ] = i d [ b [ i ] ] b'[i] = id[b[i]] b′[i]=id[b[i]]用来表示:b数组中当前数在a数组中对应的下标
那么要想b中的某个序列在a中也是其中的序列
就需要我们得到的这个b’中的某个子序列,在a中出现过就行了,同时要保证在a中的下标是顺序的
所以问题可以转化为求b’数组的最长上升子序列
具体LIS问题求法可以看 -> 这里
我们发现这个数据范围是 1 e 6 1e6 1e6的,所以我们采用贪心+二分优化,时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)
代码:
const int N = 1e6 + 10;
int id[N], n;
vector<int> vec;
int main(){
read(n);
for(int i = 1, x; i <= n; i ++) read(x), id[x] = i;
for(int i = 1, x; i <= n; i ++){ read(x);
if(!id[x]) continue;//注意:如果没出现过那就不要加进去了
if(vec.empty() || vec.back() < id[x]) vec.push_back(id[x]);
else vec[lower_bound(vec.begin(), vec.end(), id[x]) - vec.begin()] = id[x];
}write(vec.size());
return 0;
}
以上是关于AcWing 3510- 最长公共子序列 - 贪心+二分优化的主要内容,如果未能解决你的问题,请参考以下文章