1210: 最长公共子序列

该问题旨在找出给定的两个排列的最长公共子序列,条件是子序列对应元素的原始下标需保持单调性。通过动态规划,利用下标的单调性找到满足条件的序列,最后输出最长公共子序列的长度。示例中给出了一个解题思路和代码实现。
摘要由CSDN通过智能技术生成
题目描述

给出 1,2,…,n 的两个排列 P1​ 和 P2​ ,求它们的最长公共子序列。

输入

第一行是一个数 n。
接下来两行,每行为 n 个数,为自然数 1,2,…,1,2,…,n 的一个排列。

1<=n<=100000

输出

一个数,即最长公共子序列的长度。

样例输入 复制
5 
3 2 1 4 5
1 2 3 4 5
样例输出 复制
/*
    假设a序列中的a3和b序列种地b5结合的前提下
    那么a4只能和下标大于5的数结合;
    所以说;
        公共子序列满足,每个元素对应的原下标组成两个新的数组他们的单调性一样;
        列;3 2 1 4 5
            1 2 3 4 5
            取最长为3 4 5
            原下表为
            1 4 5
            3 4 5
    因此对于两段序列,取两段相同的子下标序列;
        1.下标单调性相同(同为递增)
        2.对应下标的数相同
    那么这个序列就是 公共子序列;
    所以该题可转化成 
    1.满足在对应下标的数相同的序列中,找到下表单调性相同的序列即可;
*/
#include "bits/stdc++.h"
using namespace std;
const int mxn=1e5+9,inf=0x3f3f3f3f;
int dp[mxn],a[mxn],b[mxn],n,m;
int main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>m,a[m]=i;
    for(int i=1;i<=n;i++) cin>>m,b[i]=a[m];
    memset(dp,inf,sizeof dp);
    for(int i=1;i<=n;i++) *lower_bound(dp+1,dp+n+1,b[i])=b[i];
    int x=lower_bound(dp+1,dp+1+n,inf)-dp;
    cout<<x-1<<'\n';
    return 0;
}
3
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值