蒟蒻求解

P1439 【模板】最长公共子序列

qujunhao @ 2024-09-13 18:32:40

可能我太菜了,不会求解,希望有注释谢谢


by qujunhao @ 2024-09-13 18:33:08

闭关注


by XYstarabyss @ 2024-10-03 15:50:10

#include <iostream>
using namespace std;
#define f(n,m,i) for (int i = n;i <= m;i++)
#define fc(n,m,i) for (int i = n;i >= m;i--)
#define oo 1e9 

int n,a[100001],b[100001];
int dp[100001];//记录当前最长公共子序列的元素 
int map[100001];//记录第一个排列中各元素的顺序 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //硬核快读

    cin >> n;

    f(1,n,i){
        dp[i] = 0x7fffffff;
        //初始化dp数组 

        cin >> a[i];//输入第一个排列 

        map[a[i]] = i;
        //记录第一个排列中各元素的顺序 
    }
    f(1,n,i){
        cin >> b[i];//输入第二个排列 
    }
    dp[0] = 0;
    int len = 0;//记录当前已知最长公共子序列的长度 
    f(1,n,i){//遍历第二个排列 
        int l = 0,r = len,mid;
        //二分 
        if (map[b[i]] > dp[len]){
            //如果有比当前最长公共子序列中下标最大的还大公共元素对 
            dp[++len] = map[b[i]];
            //将这个公共元素对加入最长公共子序列 
        }
        else{
            //否则找一下这个公共元素对排在当前最长公共子序列的什么地方 
            while (l < r){
                mid = (l + r) / 2;
                if (dp[mid] > map[b[i]]){
                    r = mid;
                }
                else    l = mid + 1;
            }
            dp[l] = min(map[b[i]],dp[l]);
            //比一比看一下最长公共子序列的这个地方用什么元素划算 
        }
        //f(1,len,io){
        //  cout << dp[io] << ' ';
        //}cout << endl;//调试 
    }
    cout << len;
    return 0;
}
/*
样例: 
a:  3 2 1 4 5
map:3 2 1 4 5
b:  1 2 3 4 5
dp: 3 -> 2 -> 1 -> 1,4 -> 1,4,5
len:1 -> 1 -> 1 ->  2  ->   3
*/

by qujunhao @ 2024-10-06 16:02:05

@XYstarabyss 已关注,谢谢


|