O(nlogn)实现LCS与LIS
序:
LIS与LCS分别是求一个序列的最长不下降序列序列与两个序列的最长公共子序列。
朴素法都可以以O(n^2)实现。
LCS借助LIS实现O(nlogn)的复杂度,而LIS则是通过二分搜索将复杂度从n^2中的朴素查找导致的n降至logn使之整体达到O(nlogn)的复杂度。
具体解析:
http://www.cnblogs.com/waytofall/archive/2012/09/10/2678576.html
LIS代码实现:
/*
About: LIS O(nlogn)
Auther: kongse_qi
Date:2017/04/26
*/
#include <bits/stdc++.h>
#define maxn 10005
using namespace std;
int n, x[maxn];
void Init()
{
scanf("%d", &n);
for(unsigned i = 0; i != n; ++i)
{
scanf("%d", &x[i]);
}
return ;
}
int lower_find(int cur, int t, int x[])
{
int l = 0, r = t, mid;
while(l < r-1)
{
mid = (l+r)/2;
if(x[mid] > cur) r = mid;
else l = mid+1;
}
return (x[l] >= cur ? l : r);
}
int Lis()
{
int dp[maxn], top_pos = -1, pos;
dp[++top_pos] = x[0];
for(unsigned i = 1; i != n; ++i)
{
if(x[i] > dp[top_pos])
{
dp[++top_pos] = x[i];
continue;
}
pos = lower_find(x[i], top_pos, dp);//手写或直接调用STL的lower_bound函数寻找下界
//pos = lower_bound(dp, dp+top_pos+1, x[i])-dp;
if(dp[pos] > x[i]) dp[pos] = x[i];
}
return top_pos+1;
}
int main()
{
freopen("test.in", "r", stdin);
Init();
printf("%d\n", Lis());
return 0;
}
LCS代码实现
/*
About: LCS O(nlogn)
Auther: kongse_qi
Date:2017/04/26
*/
#include <bits/stdc++.h>
#define maxn 1005
using namespace std;
int n, m, a[maxn], b[maxn];
vector<int> x[maxn];
vector<int> dp;
typedef vector<int>::iterator iterator_t;
void Init()
{
scanf("%d%d", &n, &m);
for(unsigned i = 0; i != n; ++i)
{
scanf("%d", &a[i]);
}
for(unsigned i = 0; i != m; ++i)
{
scanf("%d", &b[i]);
}
return ;
}
void Pre()
{
for(unsigned i = m-1; i != -1; --i)
{
x[b[i]].push_back(i);
}
for(unsigned i = 0; i != n; ++i)
{
if(!x[a[i]].empty())
{
for(iterator_t j = x[a[i]].begin(); j != x[a[i]].end(); ++j)
{
dp.push_back(*j);
}
}
else dp.push_back(0);
}
return ;
}
int Lis()
{
int qi[maxn], top_pos = -1, pos;
qi[++top_pos] = dp[0];
for(iterator_t i = dp.begin()+1; i != dp.end(); ++i)
{
if(*i > qi[top_pos])
{
qi[++top_pos] = *i;
continue;
}
pos = lower_bound(qi, qi+top_pos+1, *i)-qi;
if(qi[pos] > *i) qi[pos] = *i;
}
return top_pos+1;
}
int main()
{
//freopen("test.in", "r", stdin);
Init();
Pre();
printf("%d\n", Lis());
return 0;
}
自此结束。
箜瑟_qi 2017.04.26 9:01
O(nlogn)实现LCS与LIS的更多相关文章
- 最长公共子序列-LCS问题 (LCS与LIS在特殊条件下的转换) [洛谷1439]
题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列. 输入 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列. 输出 一个数,即最长公共子序列的长度 输入样例 5 ...
- BZOJ4990 (LCS转LIS)
题面 https://www.lydsy.com/JudgeOnline/problem.php?id=4990 分析 首先可以看出一个简单的DP dp[i][j]表示序列a前i个与序列b前j个连线数 ...
- uva 10635 Prince and Princess(LCS成问题LIS问题O(nlogn))
标题效果:有两个长度p+1和q+1该序列.的各种元素的每个序列不是相互同.并1~n^2之间的整数.个序列的第一个元素均为1. 求出A和B的最长公共子序列长度. 分析:本题是LCS问题,可是p*q< ...
- UVa10635 - Prince and Princess(LCS转LIS)
题目大意 有两个长度分别为p+1和q+1的序列,每个序列中的各个元素互不相同,且都是1~n^2之间的整数.两个序列的第一个元素均为1.求出A和B的最长公共子序列长度. 题解 这个是大白书上的例题,不过 ...
- BZOJ1264 [AHOI2006]基因匹配Match 【LCS转LIS】
题目链接 BZOJ1264 题解 平凡的\(LCS\)是\(O(n^2)\)的 显然我们要根据题目的性质用一些不平凡的\(LCS\)求法 这就很巧妙了,, 我们考虑\(A\)序列的每个位置可能匹配\( ...
- uva 10635 LCS转LIS
这道题两个数组都没有重复的数字,用lcs的nlogn再适合不过了 #include <iostream> #include <string> #include <cstr ...
- LCS&&LRC&&LIS问题
注:最近笔试题经常碰到DP动态规划的问题,但是由于本人没有接触过DP,笔试后看到别人家的答案简洁又漂亮,真的羡慕:难的DP自己可能不会,那再见到常见的LCS和LRS以及LIS为问题总该会吧: 资料参考 ...
- 算法心得1:由$nlogn$复杂度的LIS算法引起的思考
LIS(Longest Increasing Subsequence)是一类典型的动态规划类问题,简化描述如下: 给定$N(n) = \{1,2...,n\}$的一个排列$P(n)$,求$P(n)$中 ...
- BZOJ 1264 基因匹配Match(LCS转化LIS)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1264 题意:给出两个数列,每个数列的长度为5n,其中1-n每个数字各出现5次.求两个数列 ...
随机推荐
- java学习笔记 --- java基础语法
一.java标识符,关键字,保留字 1.标识符 用来增强程序阅读性自定义的名字.类名,变量名,方法名等都可以被称为标识符 标识符的组成: 1.由数字(0-9),字母(a-z,A-Z),下划线(_),美 ...
- Python快速入门(4)
输入输出: open() read() readine() readlines() write() pickle模块可以做序列化操作,持久保持对象的信息. 我们可以很容易的读写文件中的字符串.数值就要 ...
- CF #404 (Div. 2) D. Anton and School - 2 (数论+范德蒙恒等式)
题意:给你一个由'('和')'组成的字符串,问你有多少个子串,前半部分是由'('组成后半部分由')'组成 思路:枚举这个字符串中的所有'('左括号,它左边的所有'('左括号的个数为num1,它的右边的 ...
- Gym 101257G 24 (概率+二分)
题意: 有一道分值为sa的题,n个人比赛写这道题,按照递减的顺序给出每个人的当前分数,和每个人写不出这道题的概率,让你输出有反超现象出现的期望 思路:由于之前把题目翻译错了导致很久没有相通,后来看了别 ...
- Executor以及线程池
在应用程序中,总是会出现大量的任务,包括相同类型的和不同类型的.要快速处理这些任务,常见方法就是利用多线程,但是也不可能为每个任务都创建一个线程,这样内存也不够,并且线程的创建销毁开销很大.最好是少量 ...
- Android报错:WindowManager$BadTokenException: Unable to add window -- window has already been added
很久之前测试通过的代码,现在手机升级了Android7.0后一运行就崩溃,报出这样的错误,具体错误如下: Process: com.example.sho.android_anti_theft, PI ...
- js 模板引擎
template = document.querySelector('#template').innerHTML, result = document.querySelector('.result') ...
- web 项目中a标签传值(中文)到后台的乱码问题
web 项目中a标签传值(中文)到后台的乱码问题 jsp页面中的a标签: .............. <c:forEach items="${sellerList }" v ...
- JavaScript--------------------jQuery中.bind() .live() .delegate() .on()的区别 和 三种方式写光棒事件 动画
bind(type,[data],fn) 为每个匹配元素的特定事件绑定事件处理函数. $("a").bind("click",function(){alert( ...
- 哥哥我刚学的java---------数组插入法------------
package charufa; public class Test02 { // 插入法(插入一个数字). public static void main(String[] args) { int[ ...