LCS (nlogn)】的更多相关文章

最长上升子序列的O(n*logn)算法分析如下: 先回顾经典的O(n^2)的动态规划算法,设a[t]表示序列中的第t个数,dp[t]表示从1到t这一段中以t结尾的最长上升子序列的长度,初始时设dp [t] = 0(t = 1, 2, ..., len(a)).则有动态规划方程:dp[t] = max{1, dp[j] + 1} (j = 1, 2, ..., t - 1, 且a[j] < a[t]). 现在,我们仔细考虑计算dp[t]时的情况.假设有两个元素a[x]和a[y],满足 (1)x <…
题目连接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1576 13935381 10635 Prince and Princess Accepted C++ 0.095 2014-07-24 03:41:18 Prince and PrincessInput: Standard Input Output: Standard Output…
morestep学长出题,考验我们,第二题裸题但是数据范围令人无奈,考试失利之后,刻意去学习了下优化的算法 一.O(nlogn)的LIS(最长上升子序列) 设当前已经求出的最长上升子序列长度为len.先判断A[t]与D[len].若A [t] > D[len],则将A[t]接在D[len]后将得到一个更长的上升子序列,len = len + 1, D[len] = A [t]:否则,在D[1]..D[len]中,找到最大的j,满足D[j] < A[t].令k = j + 1,则有A [t] &…
首先介绍一下LIS和LCS的DP解法O(N^2) LCS:两个有序序列a和b,求他们公共子序列的最大长度 我们定义一个数组DP[i][j],表示的是a的前i项和b的前j项的最大公共子序列的长度,那么由于是用迭代法,所以计算DP[i][j]前,DP[i-1][j]和DP[i][j-1]就都已经计算出来了,不难理解就可以得出状态转移方程: DP[i][j]  = DP[i-1][j-1] + 1;   如果a[i] == b[j] MAX(DP[i-1][j], DP[i][j-1])  如果a[i…
标题效果:有两个长度p+1和q+1该序列.的各种元素的每个序列不是相互同.并1~n^2之间的整数.个序列的第一个元素均为1. 求出A和B的最长公共子序列长度. 分析:本题是LCS问题,可是p*q<=62500,O(pq)的算法显然会LE.在这里有一个条件,每一个序列中的各个元素互不同样,所以能够把A中元素又一次编号为1~p+1.比如,例子中A={1,7,5,4,8,3,9},B={1,4,3,5,6,2,8,9}.因此把A又一次编号为{1,2,3,4,5,6,7}.则B就是{1,4,6,3,0,…
序: 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:…
o(n^2)解法就不赘述了,直接解释o(nlogn)解法 LIS最长递增子序列: 先明确一个结论:在长度最大为len的递增序列里若末尾元素越小,该递增序列越容易和后面的子序列构造出一个更长的递增子序列.也即认为,长度为len的递增子序列中末尾元素最小的那种最需要保留.我们不妨称这个目前找到序列为到目前为止的 最优序列. 因此设置一个数组lis[i]其中 i 表示此时最大递增序列的长度,数组值表示此时达到 i 的最优序列(也即 长度为len的递增子序列中末尾元素最小的那种)的末尾元素. 那么此时只…
这个算法其实是因为LIS有NlogN的作法,把LCS转化为了LIS来做. 对于序列A{},B{},我们可以记录下来B中的每个元素在A中出现的位置,按顺序保存在一个新序列当中, 如果有多个位置按倒序写,没有就不用写,然后对这个新序列求一个LIS就是两个序列的LCS长度. 为什么这样可行呢,我们可以这样考虑,对于A序列,下标编号记为1---n1,B和A的最长公共子序列在A中对应的编号肯定是递增的, 所以B中的这些元素对应的A的编号也是递增的,为了重复计算当有多个编号时倒序存入,表示只能选一个,尽管有…
LIS(nlogn) #include<iostream> #include<cstdio> using namespace std; ; int a[maxn]; int n; int lis[maxn]; ; int find(int x){ ,r=len,m; while(l<r){ m=l+(r-l)/; if(lis[m]>=a[x]){//这里若去掉等号即为 非严格递增序列 r=m; } else{ l=m+; } } return l; } int mai…
题目链接:http://vjudge.net/contest/137498#problem/G 题意:有两个长度为p+1和q+1的序列,每个序列的中的各个元素互不相同,且都是1~n^2之间的整.两个序列的第一个元素均为1.求出A和B的最长公共子序列长度. 输入:  T  //测试组数 n p q A : p+1个数 B:q+1个数 输出:Case t: len 思路:因为n*n=62500 LCS的算法 O(pq)很慢,而且数组也开不下,所以可以转化为求LIS(O(nlogn)). 代码: #i…