1. 程式人生 > >【模板】最長公共子序列(LCS)。

【模板】最長公共子序列(LCS)。

ons 理解 思路 esp 自動 const () -- bing

看過好多人的博客,感覺要麽是太復雜要麽就是太不容易理解。

那就親自動手寫一個通俗易懂的。

先定義兩個數組,第一個數組為主,用第二個數組來匹配第一個,看能有多少可以對應上的。

所以,其實第一個數組的內容可以暫時不考慮,當知道它對應了第二個數組的哪個數字就BINGO了。

順著這個思路繼續想就可以得到以下思路:

把第一個數組離散化(記錄第一個數組變成什麽)後的數組是滿足上升的關系。

現在的問題就變成了求一個最長不下降序列。

二話不說上代碼。

------------------------------------------一道華麗的分割線------------------------------------------

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#define rg register
#define int long long
using namespace std;
inline int read(){
    rg int s=0,f=0;
    rg char ch=getchar();
    while(!isdigit(ch)) f|=(ch==‘-‘),ch=getchar();
    while(isdigit(ch)) s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
    return f?-s:s;
}
int n,len;
const int MAX=100010;
int a1[MAX],a2[MAX],f[MAX],b[MAX],c[MAX];
signed main(){
    n=read();
    for(rg int i=1;i<=n;++i){
        a1[i]=read();
        c[a1[i]]=i;
    }
    for(rg int i=1;i<=n;++i){
        a2[i]=read();
    }
    for(rg int i=1;i<=n;++i){
        if(c[a2[i]]>b[len]){
            b[++len]=c[a2[i]];
            f[i]=len;
            continue;
        }
        int k=lower_bound(b+1,b+len+1,c[a2[i]])-b;
        b[k]=c[a2[i]];
        f[i]=k;
    }
    printf("%d\n",len);
    return 0;
}

【模板】最長公共子序列(LCS)。