题目描述

给出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

Solve

首先,来看一下N2N^2N2的算法:

dp[i][j]={max(dp[i][j],dp[i−1][j−1]+1)a[i]==b[j]max(dp[i][j−1],dp[i−1][j])a[i]!=b[j]
dp[i][j]=\left\{
\begin{array}{rcl}
max(dp[i][j],dp[i-1][j-1]+1) & & {a[i]==b[j]}\\
max(dp[i][j-1],dp[i-1][j]) & & {a[i]!=b[j]}
\end{array} \right.
dp[i][j]={max(dp[i][j],dp[i−1][j−1]+1)max(dp[i][j−1],dp[i−1][j])​​a[i]==b[j]a[i]!=b[j]​

dp[i][j]dp[i][j]dp[i][j]代表aaa数组的前iii位与bbb数组的前jjj位的最长公共子序列的长度

dp[0][0]=(a[0]==b[0])dp[0][0]=(a[0]==b[0])dp[0][0]=(a[0]==b[0])

用这个方法来写,对于10510^5105的数据来说,时间和空间都是不够用的


题中已经说明了:两个数组均是1-n的排列,即:两个数组的元素是相同的,只是元素所在的位置不同。那么,两个数组的公共子序列中的元素在两个数组中的相对位置是一样的

如果按照下标给第一个数组的元素赋予新的值(按照升序),

例如:a={3,1,2,4,5};b={1,3,2,4,5}a=\{3,1,2,4,5\};b=\{1,3,2,4,5\}a={3,1,2,4,5};b={1,3,2,4,5}

old 3 1 2 4 5
new 0 1 2 3 4

对aaa进行处理后的数组为{0,1,2,3,4}\{0,1,2,3,4\}{0,1,2,3,4}

用在aaa中创建的映射关系,将bbb中的元素替换:

old 1 3 2 4 5
new 1 0 2 3 4

得到的新的bbb数组为:{1,0,2,3,4}\{1,0,2,3,4\}{1,0,2,3,4}

我们可以发现:新的bbb数组的最长上升子序列即为原两个数组的最长公共子序列

Code

/*************************************************************************

	 > Author: WZY
> School: HPU
> Created Time: 2019-02-08 15:20:18 ************************************************************************/
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 0x7f7f7f7f
const int maxn=1e6+10;
const int mod=1e9+7;
using namespace std;
int a[maxn];
int b[maxn],b1[maxn];
int vis[maxn];
int dp[maxn];
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
vis[a[i]]=i;
}
for(int i=0;i<n;i++)
{
cin>>b[i];
b1[i]=vis[b[i]];
}
int ans=0;
for(int i=0;i<n;i++)
{
int pos=lower_bound(dp,dp+ans,b1[i])-dp;
dp[pos]=b1[i];
ans=max(ans,pos+1);
}
cout<<ans<<endl;
return 0;
}

洛谷 P1439 【模板】最长公共子序列(DP,LIS?)的更多相关文章

  1. 洛谷1439:最长公共子序列(nlogn做法)

    洛谷1439:最长公共子序列(nlogn做法) 题目描述: 给定两个序列求最长公共子序列. 这两个序列一定是\(1\)~\(n\)的全排列. 数据范围: \(1\leq n\leq 10^5\) 思路 ...

  2. 洛谷P2516 [HAOI2010]最长公共子序列(LCS,最短路)

    洛谷题目传送门 一进来就看到一个多月前秒了此题的ysn和YCB%%% 最长公共子序列的\(O(n^2)\)的求解,Dalao们想必都很熟悉了吧!不过蒟蒻突然发现,用网格图貌似可以很轻松地理解这个东东? ...

  3. 洛谷 P2516 [HAOI2010]最长公共子序列

    题目传送门 解题思路: 第一问要求最长公共子序列,直接套模板就好了. 第二问要求数量,ans[i][j]表示第一个字符串前i个字符,第二个字符串前j个字符的最长公共子序列的数量 如果f[i][j]是由 ...

  4. 洛谷P2516 [HAOI2010]最长公共子序列

    题目描述 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X="x0,x1,-,xm-1",序列Y=& ...

  5. 【Luogu P1439】最长公共子序列(LCS)

    Luogu P1439 令f[i][j]表示a的前i个元素与b的前j个元素的最长公共子序列 可以得到状态转移方程: if (a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1; d ...

  6. LCS最长公共子序列~dp学习~4

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 Palindrome Time Limit: 4000/2000 MS (Java/Others ...

  7. POJ 1458 最长公共子序列(dp)

    POJ 1458 最长公共子序列 题目大意:给出两个字符串,求出这样的一 个最长的公共子序列的长度:子序列 中的每个字符都能在两个原串中找到, 而且每个字符的先后顺序和原串中的 先后顺序一致. Sam ...

  8. 【BZOJ2423】[HAOI2010]最长公共子序列 DP

    [BZOJ2423][HAOI2010]最长公共子序列 Description 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字 ...

  9. hdu 1159 Common Subsequence(最长公共子序列 DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1159 Common Subsequence Time Limit: 2000/1000 MS (Jav ...

  10. 38-最长公共子序列(dp)

    最长公共子序列 https://www.nowcoder.com/practice/c996bbb77dd447d681ec6907ccfb488a?tpId=49&&tqId=293 ...

随机推荐

  1. 【模板】滑动窗口最值(单调队列)/洛谷P1886

    题目链接 https://www.luogu.com.cn/problem/P1886 题目大意 有一个长为 \(n\) 的序列 \(a\) ,以及一个大小为 \(k\) 的窗口.现在这个从左边开始向 ...

  2. 日常Java 2021/10/10

    多态就是同一个行为具有多个不同表现形式的能力 多态就是同一个接口,使用不同的实例而执行不同操作 多态的优点 1.消除类型之间的耦合关系 2.可替换性 3.可扩充性 4.接口性 5.灵活性 6.简化性 ...

  3. 大数据学习day29-----spark09-------1. 练习: 统计店铺按月份的销售额和累计到该月的总销售额(SQL, DSL,RDD) 2. 分组topN的实现(row_number(), rank(), dense_rank()方法的区别)3. spark自定义函数-UDF

    1. 练习 数据: (1)需求1:统计有过连续3天以上销售的店铺有哪些,并且计算出连续三天以上的销售额 第一步:将每天的金额求和(同一天可能会有多个订单) SELECT sid,dt,SUM(mone ...

  4. EasyExcel读写Excel

    使用过 poi 的开发同学可能都有此体会,每次都要写一坨代码,最后的代码如下面一样: 这样的代码是不是又臭又长?当字段数量多的时候,一不小心还容易写错.阿粉还记得当初使用 poi 导出一个二十多字段的 ...

  5. Linux学习 - 脚本安装包

    脚本安装包不是独立的软件包类型,常见安装的是源码包

  6. Mybatis-运行原理

    一.mybatis分层图 二.运行流程 根据全局配置文件创建sqlSessionFactory对象 根据全局配置文件的io流来构建SqlSessionFactoryBuilder对象: 解析(XmlC ...

  7. docker创建tomcat容器无法正常访问

    记一次创建tomcat docker容器后访问是404,进入到tomcat docker容器后发现webapps是空的 1.挂载 docker run -v localConfigFile:/cont ...

  8. mybtis入门

    1.编写持久化对象 public class User { private String id;//用户编号 private String username;//用户名 private String ...

  9. 【力扣】剑指 Offer 50. 第一个只出现一次的字符

    在字符串 s 中找出第一个只出现一次的字符.如果没有,返回一个单空格. s 只包含小写字母. 示例: s = "abaccdeff"返回 "b" s = &qu ...

  10. 南邮CTF-MISC-Remove Boyfriend

    Remove Boyfriend 打开wireshark,找到关键字部分Remove Boyfriend 在第五行 在此行右击 点击追踪流 选择TCP流,可以分析出流量的传输过程 通过上面的执行列表 ...