洛谷P3402 最长公共子序列
来源:互联网 发布:c语言实现arp欺骗 编辑:程序博客网 时间:2024/06/05 10:17
题目背景
DJL为了避免成为一只咸鱼,来找Johann学习怎么求最长公共子序列。
题目描述
经过长时间的摸索和练习,DJL终于学会了怎么求LCS。Johann感觉DJL孺子可教,就给他布置了一个课后作业:
给定两个长度分别为n和m的序列,序列中的每个元素都是正整数。保证每个序列中的各个元素互不相同。求这两个序列的最长公共子序列的长度。
DJL最讨厌重复劳动,所以不想做那些做过的题。于是他找你来帮他做作业。
输入输出格式
输入格式:
第一行两个整数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。
输出格式:
一行一个整数,表示两个数列的最长公共子序列的长度。
输入输出样例
输入样例#1:
6 6
1 3 5 7 9 8
3 4 5 6 7 8
输出样例#1:
4
说明
对于40%的数据,n, m≤3000
对于100%的数据,n, m≤300000
【题解】
为什么前面的神牛都用了STL函数upper——bound,我这个小蒟蒻不懂。。。
于是乎,我写了个没用这个STL函数的代码,速度慢到爆(最后一个点0.9s+)。
此题难点是
1、数据范围过大,这需要用不定长数组map(不懂看度娘)
2、此题数据是用来卡AC的,所以要先将其转化为一个子序列(map的映射功能),再用优化算法——LIS的n*logn算法。
3、LIS的n*logn算法:D[i]保留满足F[i] = k的所有A[i]中的最小值。F[i]表示从1到i这一段中以i结尾的最长上升子序列的长度。设当前已经求出的最长上升子序列长度为len。先判断A[i](一个子序列)与D[len],若A[i] > D[len],则将A[i]接在D[len]后将得到一个更长的上升子序列,len = len + 1,D[len+1] = A[i];否则,在D[1]..D[len]中,找到最大的j,满足D[j] < A[i].令k = j + 1,则有D[j] < A[i] <= D[k],将A[i]接在D[j]后将得到一个更长的上升子序列,同时更新D[k] = A[i].最后,len即为所要求的最长上升子序列的长度。
#include<cstdio>#include<cstring>#include<iostream>#include<string>#include<cmath>#include<algorithm>#include<map>using namespace std;map<int,int>f;//不定长数组,相当于一种映射,具体请问度娘 int a[300009]={},n,m,c[400009]={},d[260000]={},aa,bb;int lcs(){ int w,i,j; for(i=1;i<=n;i++) c[i]=f[a[i]];//c数组记录下第一个子序列中的数在第二个子序列中的位置 int s=1; while(c[s]==0)//c数组元素为0说明第一个子序列的数在第二个子序列中不存在,即是在第一个子序列有, //第二个子序列没有的数 c[s]=999999,s++;//先把前面的数二分时扔到最后面,直到发现第一个两子序列共有数为止 //ps:前三句话其实都没必要,只是不剪点枝肯定TLE d[1]=c[1];//第一个数当然直接放第一个 int t=1; for(i=2;i<=n;i++)//二分找出一个个公共子序列元素所在位置 { int l=1,r=t,mid;//因为从1开始,比最小两子序列共有数小的数(如0)被放在d[0]不断覆盖(遗忘) while(l<=r) { mid=(l+r)>>1;//>>1等价于/2 if(d[mid]<c[i]) l=mid+1; else r=mid-1; } d[l]=c[i]; if(l>t)//如果发现找出的位置在最后面,那就加长度 t++; } return t;}int main(){ scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int q; for(int i=1;i<=m;i++) { scanf("%d",&q); f[q]=i;//第二个子序列记录下位置 } int ans=lcs();//LIS的n*logn算法 cout<<ans<<endl; return 0;}
- 洛谷P3402 最长公共子序列
- [P3402]最长公共子序列
- P3402 最长公共子序列(nlogn)
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列...
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- 最长公共子序列
- HIVE入门一之数据库DDL语句
- 【字典树】小练
- laravel 5.4框架路由get路由奇怪设定 有人能给我解释下为什么这样的么?
- PHP如何在MVC模型中使用回调函数
- DLL的创建和调用实例教程
- 洛谷P3402 最长公共子序列
- Leetcode495 Teemo Attacting
- springboot-cloud-3-Hystrix
- Android 剪切板
- ionic配置页面间跳转的URL
- hdu3709 Balanced Number
- 使用Nexus搭建Maven本地仓库
- idea 2017注册码
- 几种排序算法的讲解(二)