1. 程式人生 > 其它 >最長公共子序列問題(LCS) 洛谷 P1439

最長公共子序列問題(LCS) 洛谷 P1439

題目:P1439 【模板】最長公共子序列 - 洛谷 | 電腦科學教育新生態 (luogu.com.cn)

關於LCS問題,可以通過離散化轉換為LIS問題,於是就可以使用STL二分的方法O(nlogn)解決LCS問題!

先將a陣列與一個遞增的數列1,2,3...n兩兩對應(t陣列),再把b陣列中每個數在a陣列中的位置表示成c陣列,

經過此番操作,a與b的公共子序列在c陣列中就是呈遞增狀態的。

程式碼:

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int a[N], b[N], c[N], r[N], t[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i)
    {
        cin >> a[i];
        t[a[i]] = i;//a陣列與遞增數列1,2,3...n對應
    }
    for (int i = 1; i <= n; ++i)
        cin >> b[i];
    for (int i = 1; i <= n; ++i)
    {
        c[i] = t[b[i]];//將b陣列中每個元素在a陣列中的位置寫入c陣列
    }
    int cnt = 0;

    for (int i = 1; i <= n; ++i)//使用求解LIS問題的STL二分方法
    {
        if (c[i] > r[cnt])
            r[++cnt] = c[i];
        else
        {
            int pos = lower_bound(r + 1, r + 1 + cnt, c[i]) - r;
            r[pos] = c[i];
        }
    }
    cout << cnt << endl;

    return 0;
}