最长公共子序列

最长公共子序列

前置知识

子序列:一个字符串 'abc' ,它的子序列有 'a', 'b', 'c', 'ab', 'ac', 'bc', 'abc'

全排列,一个大小为 (N) 的数组,任意一个元素 (a_i) 满足 (1 ≤ a_i ≤ N),并且每个元素互不相同。

思路

  1. 对于一个全排列的,可以考虑先把它进行处理一下,处理的方法,就是对它进行一个离散化

    使其变成一个 (1,2,3,...,N-1,N) 的排列,那么另一个序列就会发生改变。

  2. 之后对求解的问题就会变成求一个最长上升子序列的问题。

  3. 上升子序列存在一个状态转化的问题,使用 vector 存一个数组,

    (a_i>) vector 中的最后一个元素的时候,在 vector 添加这个元素,

    小于的时候,对 vector 对应的那个位置进行更新,那个位置就是对应的前一项小于 (a_i)

    对应的后一项大于 (a_i)更新那个位置值的原因是因为,在此之前的 (a_i) 不会在对它进行使用,

    而对它进行更新的话,可以让 vector 中存的元素尽量的小,更加方便后续元素的进入,

    并且不会影响最长公共序列的长度的值。

    实际上这是通过递推的思路进行解决,考虑前一个状态,并且对前一个状态不产生影响。

代码

这个是洛谷最长公共子序列的板子题

点我,快点我

#include <map>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
    int N,x;
    map<int,int>m;
    cin>>N;
    for(int i=0;i<N;++i){
        cin>>x;m[x]=i+1;
    }
    vector<int>v;
    for(int i=0;i<N;++i){
        cin>>x;x=m[x];
        if(v.size()==0||x>v[v.size()-1])v.push_back(x);
        else{
            int pos=lower_bound(v.begin(),v.end(),x)-v.begin();
            v[pos]=x;
        }
    }
    cout<<v.size()<<endl;
    return 0;
}
新赛季的开始
原文地址:https://www.cnblogs.com/VagrantAC/p/12489635.html