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

题目qwq

(第一道蓝题)

据说是用了hash的思想(?)

总之是先把第一个序列每个数出现的顺序记下来(其实第一个序列的数字不用记),

然后第二个序列的每个数都对照它的顺序,这样只要得到一个升序的序列就行了qwq

如果遇到出现顺序在前面的数,就用二分法找一下它的位置,然后把原来存下来的顺序覆盖掉

#include<cstdio>
using namespace std;
int f[100005],ans[100005];
int n,sum;
int k,l,r,now,mid;
int main() {
    scanf("%d",&n);
    for(int i = 1; i <= n; i++) {
        scanf("%d",&k);
        f[k] = i;
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d",&k);
        now = f[k];
        if(now > ans[sum])
            ans[++sum] = now;
        else {
            l = 1,r = sum;
            while(l < r) {
                mid = (l+r)/2;
                if (ans[mid]<now)l = mid+1;
                else r = mid;
            }
            ans[l] = now;
        }
    }
    printf("%d",sum);
    return 0;
}

原文地址:https://www.cnblogs.com/mogeko/p/9859379.html

时间: 2024-11-09 03:38:57

luogu P1439 【模板】最长公共子序列的相关文章

模板 最长公共子序列

[模板]最长公共子序列 1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 6 char s1[1000],s2[1000]; 7 int len1,len2,dp[1000][1000],mark[1000][1000];//如果数据太大,dp数组可以考虑滚动数组 8 9 void LCS() 10 { 11 int i,j; 12 mem

【Luogu】P3402最长公共子序列(LCS-&gt;nlognLIS)

题目链接 SovietPower 的题解讲的很清楚.Map或Hash映射后用nlogn求出LIS.这里只给出代码. #include<cstdio> #include<cctype> #include<map> #include<algorithm> using namespace std; map<int,int> vis; inline long long read(){ long long num=0,f=1; char ch=getcha

Luogu 1439 【模板】最长公共子序列

题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子序列的长度 输入输出样例 输入样例#1: 5 3 2 1 4 5 1 2 3 4 5 输出样例#1: 3 说明 [数据规模] 对于50%的数据,n≤1000 对于100%的数据,n≤100000 [题解] 首先不难想到的是将其转化成一个序列的最长上升子序列 由于两个序列均为1~n的排列,在将其中一个

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

神TM模板..我本来想休闲一下写点水题的... 开始做的时候直接敲了一个O(N2)的算法上去,编译的时候才发现根本开不下.. 好了,谈回这道题. 先不加证明的给出一种算法. 若有一组数据 2 4 2 5 1 3 2 5 4 1 3 那么我们令 4 2 5 1 3 | | | | | 1 2 3 4 5 第三行的数据就变成 2 3 1 4 5 很明显,答案是这个数据的最长上升子序列,即4 == 2 3 4 5,即原数列的2 5 1 3. 现在来大概的介绍一下这样做的原因. 首先,观察题目,注意到这

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

CSDN同步 原题链接 简要题意: 给定两个 \(1\) ~ \(n\) 的排列,求其 最长公共子序列. 嗯,下面给出若干算法吧. 算法一 不管它是 \(1\) ~ \(n\) 的排列这一性质. 求 \(\text{LCS}\)(即最长公共子序列)的套路方法: 用 \(f_{i,j}\) 表示 \(a_1\) ~ \(a_i\) 和 \(b_1\) ~ \(b_j\) 的最长公共子序列.那么不考虑边界问题,则存在: \[f_{i,j} = \begin{cases} f_{i-1,j-1}+ 1

【luogu1439】 【模板】最长公共子序列 [动态规划][LIS最长上升子序列][离散化]

P1439 [模板]最长公共子序列 此思路详见luogu第一个题解 一个很妙的离散化 刘汝佳蓝书上面的LIS 详见蓝书 d[i]以i为结尾的最长上升子序列的长度     g[i]表示d值为i的最小状态的编号即长度为i的上升子序列的最小末尾值 1 for(int i=1;i<=n;++i) scanf("%d",&a[i]); 2 for(int i=1;i<=n;++i) 3 { 4 int k=lower_bound(g+1,g+1+n,a[i])-g; 5 d[

luogu P3402 最长公共子序列

题目背景 DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列. 题目描述 经过长时间的摸索和练习,DJL终于学会了怎么求LCS.Johann感觉DJL孺子可教,就给他布置了一个课后作业: 给定两个长度分别为n和m的序列,序列中的每个元素都是正整数.保证每个序列中的各个元素互不相同.求这两个序列的最长公共子序列的长度. DJL最讨厌重复劳动,所以不想做那些做过的题.于是他找你来帮他做作业. 输入输出格式 输入格式: 第一行两个整数n和m,表示两个数列的长度. 第二行一行n个整数a

【luogu 1439 最长公共子序列】

题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出格式: 一个数,即最长公共子序列的长度 输入输出样例 输入样例#1: 复制 5 3 2 1 4 5 1 2 3 4 5 输出样例#1: 复制 3 说明 [数据规模] 对于50%的数据,n≤1000 对于100%的数据,n≤100000 [题解]       ①LCS->LIS       ②树状数组维护nlogn LIS #i

【模板】最长公共子序列(二维偏序)

给出1-n的两个排列P1和P2,求它们的最长公共子序列. 洛谷1439 1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int maxn=100010; 5 int n,x,ans,tmp,pos[maxn],t[maxn]; 6 void read(int &k){ 7 k=0; int f=1; char c=getchar(); 8 while(c<'0'||c>

51Nod - 1006 最长公共子序列Lcs模板

给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列. Input 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000)Output输出最长的子序列,如果有多个,随意输出1个. Sample Input abcicba abdkscab Sample Output abca 只能求最长公共子序列的长度,不能输出这个串是什么