题面

https://www.lydsy.com/JudgeOnline/problem.php?id=4990

分析

首先可以看出一个简单的DP
dp[i][j]表示序列a前i个与序列b前j个连线数量
dp[i][j]=max(dp[i−1][j],dp[i][j−1],dp[i−1][j−1](∣a[i]−b[j]∣<=4))
这样DP的时间复杂度为O(n^2)
发现该方程除了转移的判断条件之外和LCS并无什么不同,因此可考虑LCS的优化方法

提示:阅读下面内容前,请先确保自己掌握一般情况下LCS转LIS的过程,以及LIS的O(nlog2n)O(nlog_2n)算法

考虑LCS转LIS,原本的方法是记录a[i]中每个值的位置pos,将b[i]转化为pos[b[i]]
既然∣a[i]−b[j]∣<=4都可杯看做“相等”
则我们对于每个b[i]±j (0<=j<=4),将pos[b[i]±j]加入数组c,求c的LIS即为答案
但注意到每个点只能连一条边,也就是对于每个b[i],9个b[i]±j中只能选一个加入LIS
所以将9个一组从大到小排序,再拼起来,这样每组数中至多有一个数被选进LIS,(若选两个,则c[i]>c[i+1],矛盾)
时间复杂度O(nlog_2n)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define maxn 100005
using namespace std;
int n;
int a[maxn],b[maxn];
int pos[maxn];
vector<int>tmp;
vector<int>c;
int s[maxn*9];
int m;
int cmp(int x,int y) {
return x>y;
}
int solve() {
for(int i=1;i<=n;i++){
tmp.clear();
for(int j=0;j<=4;j++){
if(b[i]+j<=n) tmp.push_back(pos[b[i]+j]);
if(b[i]-j>=1) tmp.push_back(pos[b[i]-j]);
}
sort(tmp.begin(),tmp.end(),cmp);
int t=tmp.size();
for(int j=0;j<t;j++){
c.push_back(tmp[j]);
}
}
int m=c.size();
// for(int i=0;i<m;i++) printf("%d ",c[i]);
// printf("\n");
int top=0;
for(int i=0; i<m; i++) {
if(c[i]>s[top]) {
s[++top]=c[i];
} else {
int tmp=lower_bound(s+1,s+1+top,c[i])-s;
s[tmp]=c[i];
}
}
return top;
} int main() {
scanf("%d",&n);
for(int i=1; i<=n; i++) {
scanf("%d",&a[i]);
pos[a[i]]=i;
}
for(int i=1; i<=n; i++) {
scanf("%d",&b[i]);
}
printf("%d\n",solve());
}

BZOJ4990 (LCS转LIS)的更多相关文章

  1. O(nlogn)实现LCS与LIS

    序: LIS与LCS分别是求一个序列的最长不下降序列序列与两个序列的最长公共子序列. 朴素法都可以以O(n^2)实现. LCS借助LIS实现O(nlogn)的复杂度,而LIS则是通过二分搜索将复杂度从 ...

  2. 最长公共子序列-LCS问题 (LCS与LIS在特殊条件下的转换) [洛谷1439]

    题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出 一个数,即最长公共子序列的长度 输入样例 5 ...

  3. UVa10635 - Prince and Princess(LCS转LIS)

    题目大意 有两个长度分别为p+1和q+1的序列,每个序列中的各个元素互不相同,且都是1~n^2之间的整数.两个序列的第一个元素均为1.求出A和B的最长公共子序列长度. 题解 这个是大白书上的例题,不过 ...

  4. BZOJ 1264 基因匹配Match(LCS转化LIS)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1264 题意:给出两个数列,每个数列的长度为5n,其中1-n每个数字各出现5次.求两个数列 ...

  5. uva 10635 Prince and Princess(LCS成问题LIS问题O(nlogn))

    标题效果:有两个长度p+1和q+1该序列.的各种元素的每个序列不是相互同.并1~n^2之间的整数.个序列的第一个元素均为1. 求出A和B的最长公共子序列长度. 分析:本题是LCS问题,可是p*q< ...

  6. LCS and LIS

    LCS #include<bits/stdc++.h> using namespace std; typedef long long ll; int n,m; char s[1005],t ...

  7. BZOJ1264 [AHOI2006]基因匹配Match 【LCS转LIS】

    题目链接 BZOJ1264 题解 平凡的\(LCS\)是\(O(n^2)\)的 显然我们要根据题目的性质用一些不平凡的\(LCS\)求法 这就很巧妙了,, 我们考虑\(A\)序列的每个位置可能匹配\( ...

  8. uva 10635 LCS转LIS

    这道题两个数组都没有重复的数字,用lcs的nlogn再适合不过了 #include <iostream> #include <string> #include <cstr ...

  9. Uva 10635 Prince and Princess (LCS变形LIS)

    直接LCS是时间复杂度是O(p*q)的,但是序列元素各不相同,只要把其中一个序列映射成有序的, 另外一个序列再做相同的映射,没有的直接删掉,就变成了求另一个序列LIS. #include<bit ...

随机推荐

  1. BSOJ5458 [NOI2018模拟5]三角剖分Bsh 分治最短路

    题意简述 给定一个正\(n\)边形及其三角剖分,每条边的长度为\(1\),给你\(q\)组询问,每次询问给定两个点\(x_i\)至\(y_i\)的最短距离. 做法 显然正多边形的三角剖分是一个平面图, ...

  2. SpringCloud学习系列-Rest微服务构建

    总体介绍 承接着我们的springmvc+mybatis+mysql初级高级课程,以Dept部门模块做一个微服务通用案例Consumer消费者(Client)通过REST调用Provider提供者(S ...

  3. [洛谷P2567] SCOI2010 幸运数字

    问题描述 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是&quo ...

  4. 6362. 【NOIP2019模拟2019.9.18】数星星

    题目描述 题解 一种好想/好写/跑得比**记者还快的做法: 对所有询问排序,按照R递增的顺序来处理 维护每个点最后一次被覆盖的时间,显然当前右端点为R时的答案为所有时间≥L的点的权值之和 LCT随便覆 ...

  5. CSS3制作太极图以及用JS实现旋转太极图

     太极图可以理解为一个一半黑一半白的半圆,上面放置着两个圆形,一个黑色边框白色芯,一个白色边框黑色芯. 1.实现黑白各半的圆形. .box{ width:200px;height:200px; bor ...

  6. SpringMVC开发手册

    title: SpringMvc -- 开发手册 date: 2018-11-15 22:14:22 tags: SpringMvc categories: SpringMvc #分类名 type: ...

  7. MSSQL 如何导出db所有用户权限创建语句

    use dbgoDECLARE @Database varchar(255),@loginName varchar(255),@roleName varchar(255),@sql nvarchar( ...

  8. mysql 无法远程连接 没有监听端口

    centos yum安装mysql: 远程连接完成用户授权和防火墙配置,可还是连接不上. 发现mysql没有监听3306端口. 修改mysql配置文件 vi /etc/my.conf 注释掉以下行,重 ...

  9. you have not created a boot efi partition

    rhel6.8 自定义分区,创建 /boot/efi 分区找不到”EFI System Partition“文件系统, 选其他文件系统 next时都提示:you have not created a ...

  10. windows 10中使用命令行关掉占用指定端口的程序

    通过netstat -ano与findstr命令结合查询到带有9080端口的监听信息,图中最后一列为监听程序的PID 通过tasklist命令与findstr命令结合查询到指定PID对应的应用程序 使 ...