Luogu 3402 最长公共子序列(二分,最长递增子序列)
Luogu 3402 最长公共子序列(二分,最长递增子序列)
Description
经过长时间的摸索和练习,DJL终于学会了怎么求LCS。Johann感觉DJL孺子可教,就给他布置了一个课后作业:
给定两个长度分别为n和m的序列,序列中的每个元素都是正整数。保证每个序列中的各个元素互不相同。求这两个序列的最长公共子序列的长度。
DJL最讨厌重复劳动,所以不想做那些做过的题。于是他找你来帮他做作业。
Input
第一行两个整数n和m,表示两个数列的长度。
第二行一行n个整数$$a_1,a_2,…,a_n,保证1≤a_i≤10^9$$。
第三行一行m个整数$$b_1,b_2,…,b_m,保证1≤b_i≤10^9$$。
对于40%的数据,n, m≤3000
对于100%的数据,n, m≤300000
Output
一行一个整数,表示两个数列的最长公共子序列的长度。
Sample Input
6 6
1 3 5 7 9 8
3 4 5 6 7 8
Sample Output
4
Http
Luogu:https://www.luogu.org/problem/show?pid=3402
Source
二分
解决思路
这道题的弱化版在这里。
因为数据加强了,我们不能使用弱化版中的动态规划方法了。
题目中给出了元素互不相同的条件。我们可以将求最长公共子序列(LCS)转化为求最长递增子序列(LIS)。
读入A数组的时候,我们定义一个Map[x]表示数x对应的编号,Map[x]=i;这样就相当于把数组A变成了一个递增的序列。
如果我们把B数组里的数都按照A中的规则转置一下,这个题目就变成求B的最长递增子序列了,具体操作如下:
然后在处理B数组的时候(假设我们现在处理数字x),先让x=Map[x]如果此时x==0则说明原来的数字x并没有在数组A中出现过,所以自然也不会成为最长公共子序列的解,直接舍去即可。
这时我们将找到的最长递增子序列放入一个vector(这里用Arr表示),并保证其有序。若x(这个x是用Map转置后的)比vector里所有元素都大(即比Arr[Arr.size()-1]大),则直接将其放到队尾;否则二分查找第一个比x大的元素并替换之。
相信你也发现了,这个算法的核心思路是贪心,我们可以看到,它是让Arr中的元素尽可能的小,以此来求出最长递增子序列,也就可以求出原题的最长公共子序列。
需要注意的是,用这种算法求最长递增子序列只能求出其长度,Arr中的数不一定就是最后要求的最长递增子序列。(为什么呢?仔细想一想)
PS:这个题目真心坑爹,不仅要用上面的这个算法,读入还必须用getchar()读入优化,就连scanf都会超时,真是……
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
int n,m;
map<int,int> Map;
vector<int> Arr;
int read();//读入优化,一定要打
int main()
{
int x;
n=read();
m=read();
for (int i=1;i<=n;i++)
{
//scanf("%d",&x);
Map[read()]=i;
}
for (int i=1;i<=m;i++)//将LCS问题转换为LIS问题,降低时间复杂度
{
//scanf("%d",&x);
x=Map[read()];
if (x==0)
continue;
if ((Arr.size()==0)||(x>Arr[Arr.size()-1]))//如果比其中的都大,直接放到后面
Arr.push_back(x);
else//否则,替换第一个比它大的
*lower_bound(Arr.begin(),Arr.end(),x)=x;
}
cout<<Arr.size()<<endl;//Arr的大小就是最后最长子序列的大小
return 0;
}
int read()
{
int x=0;
int k=1;
char ch=getchar();
while (((ch<'0')||(ch>'9')) &&(ch!='-'))
ch=getchar();
if (ch=='-')
{
k=-1;
ch=getchar();
}
while ((ch<='9')&&(ch>='0'))
{
x=x*10+ch-48;
ch=getchar();
}
return x*k;
}
Luogu 3402 最长公共子序列(二分,最长递增子序列)的更多相关文章
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...
- DP:LCS(最长公共子串、最长公共子序列)
1. 两者区别 约定:在本文中用 LCStr 表示最长公共子串(Longest Common Substring),LCSeq 表示最长公共子序列(Longest Common Subsequence ...
- 删除部分字符使其变成回文串问题——最长公共子序列(LCS)问题
先要搞明白:最长公共子串和最长公共子序列的区别. 最长公共子串(Longest Common Substirng):连续 最长公共子序列(Longest Common Subsequence,L ...
- 《算法导论》读书笔记之动态规划—最长公共子序列 & 最长公共子串(LCS)
From:http://my.oschina.net/leejun2005/blog/117167 1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要 ...
- 【ZH奶酪】如何用Python计算最长公共子序列和最长公共子串
1. 什么是最长公共子序列?什么是最长公共子串? 1.1. 最长公共子序列(Longest-Common-Subsequences,LCS) 最长公共子序列(Longest-Common-Subseq ...
- C语言 · 最长公共子序列 · 最长字符序列
算法提高篇有两个此类题目: 算法提高 最长字符序列 时间限制:1.0s 内存限制:256.0MB 最长字符序列 问题描述 设x(i), y(i), z(i)表示单个字符,则X={x( ...
- 最长公共子序列&最长公共子串
首先区别最长公共子串和最长公共子序列 LCS(计算机科学算法:最长公共子序列)_百度百科 最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. 最长公共子序列: http ...
- [Python]最长公共子序列 VS 最长公共子串[动态规划]
前言 由于原微软开源的基于古老的perl语言的Rouge依赖环境实在难以搭建,遂跟着Rouge论文的描述自行实现. Rouge存在N.L.S.W.SU等几大子评估指标.在复现Rouge-L的函数时,便 ...
- 最长公共子序列/子串 LCS(模板)
首先区分子序列和子串,序列不要求连续性(连续和不连续都可以),但子串一定是连续的 1.最长公共子序列 1.最长公共子序列问题有最优子结构,这个问题可以分解称为更小的问题 2.同时,子问题的解释可以被重 ...
- 【转】最长公共子序列(LCS),求LCS长度和打印输出LCS
求LCS的长度,Java版本: public static int LCS(int[]a,int[] b) { int [][]c=new int[a.length+1][b.length+1]; f ...
随机推荐
- 微信小程序封装http访问网络库实例代码
之前都是使用LeanCloud为存储,现在用传统API调用时做如下封装 var HOST = 'http://localhost/lendoo/public/index.php/'; // 网站请求接 ...
- nodeJS之fs文件系统
前面的话 fs文件系统用于对系统文件及目录进行读写操作,本文将详细介绍js文件系统 概述 文件 I/O 是由简单封装的标准 POSIX 函数提供的. 通过 require('fs') 使用该模块. 所 ...
- 从零开始的JS生活(一)——JS简介、变量及基本结构
本K在经过三个静态站制作的狂风暴雨之后,终于开始了JavaScript的学习.作为一只从来没有正儿八经接受过计算机语言的小白,居然能够跟上浩哥的课程进度,我的内心都被我的才智震惊到了,果然本K是天生丽 ...
- Centos 执行shell命令返回127错误
shell脚本功能:连接mysql,自动创建数据库,脚本如下 mysql -h$MYSQL_IP -u$MYSQL_USER -p$MYSQL_PASSWORD --default-character ...
- 深度解析 H.265 视频解决方案
又拍云上线了 H.265 从编码解码到 CDN 分发,完整的端到端的自适应解决方案:提供视频上传.视频存储.视频编码.视频分发适配.视频解码等功能.又拍云希望能以云服务的方式将大公司才能长期支付使用的 ...
- XCode 8.3 Automatically manage signing 问题
记录iOS证书问题 无意中选择了Personal team,后台自动生成bundle identifier:com.xxx.project,导致不能在Organization team创建,而且在de ...
- javascript的八张图
- javaCV开发详解之7:让音频转换更加简单,实现通用音频编码格式转换、重采样等音频参数的转换功能(以pcm16le编码的wav转mp3为例)
javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...
- 水平方向的RecyclerView
最近做了一个项目需要实现一个卡片式的水平滑动,但是不能手势滑动,点击卡片上的按钮之后滑动到下一个卡片,所以想到用RecyclerView实现,去掉它的手势滑动,点击按钮之后再代码控制滑动到下一个卡片. ...
- JVM高级特性-一、java内存结构区域介绍
区域划分: java虚拟机在执行程序的过程中,将内存分为功能不同的几个区域,如下图: 此图列出了内存划分的各个区域,其中 线程私有的:程序计数器.虚拟机栈.本地方法栈 线程共享的:堆.方法区 下面,逐 ...