LIS(最长递增子序列)和LCS(最长公共子序列)的总结

2024-08-24 04:08

本文主要是介绍LIS(最长递增子序列)和LCS(最长公共子序列)的总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

LIS(最长递增子序列)和LCS(最长公共子序列)的总结

最长公共子序列(LCS):O(n^2)

两个for循环让两个字符串按位的匹配:i in range(1, len1) j in range(1, len2)
s1[i - 1] == s2[j - 1], dp[i][j] = dp[i - 1][j -1] + 1;
s1[i - 1] != s2[j - 1], dp[i][j] = max (dp[i - 1][j], dp[i][j - 1]);
初始化:dp[i][0] = dp[0][j] = 0;

伪代码:
    dp[maxn1][maxn2];s1[maxn1],s2[maxn2];p[maxn1][maxn2][2];//initfor i in range(0, len1):dp[i][0] = 0;else:;for i in range(0, len2):dp[0][i] = 0;else:;for i in range(1, len1):for j in range(1, len2):if s1[i] == s2[j]:dp[i][j] = dp[i - 1][j - 1] + 1;p[i][j][0] = i - 1;p[i][j][1] = j - 1;else:if dp[i - 1][j] > dp[i][j - 1]:dp[i][j] = dp[i - 1][j];p[i][j][0] = i - 1;p[i][j][1] = j;else:dp[i][j] = dp[i][j - 1];p[i][j][0] = i;p[i][j][1] = j - 1;else:;else:;return dp[len1][len2];//path 非递归function print_path(len1, len2):if (dp[len1][len2] == 0)return;printf_path(p[len1][len2][0], p[len1][len2][1]);if s1[len1] == s2[len2]:printf:s1[len1];end function;

题目:UVA - 531Compromise UVA - 10066The Twin Towers UVA - 10192Vacation
uva10405 - Longest Common Subsequence

最长递增子序列(LIS):O(n^2)

从左到右的求前i长度的序列的最长递增子序列的长度,状态转移方程:
dp[i] = Max(dp[j] + 1);i in range(1, len); j in range(1, i - 1);

伪代码
    s[maxn],dp[maxn];for i in range(1, len):dp[i] = 1;int maxlen = 1;for i in range(2, len):for j range(1, i - 1):if s[i] > s[j]:dp[i] = Max(dp[i], dp[j] + 1);else:maxlen = max(maxlen, dp[i]);else:;return maxlen;//path递归function print_path(maxlen):if maxlen == 0:return;for i in range(1, len):if dp[i] == maxlen:print_path(maxlen - 1);printf:s[i];end function;

题目: UVA - 10599Robots(II)

最长递增子序列O(n * logn)

还是从左往右的求前i长度的序列的最长递增子序列长度,但是再确定dp[j]最大值的时候还要用一层循环来查找,这样比较低效.如果把前面的i长度序列出现的最长递增子序列储存起来,那么查找的时候用二分就可以做到O(logn)的复杂度。
用一个LIS数组来储蓄前i序列的最长递增子序列,查找第i个数字的时候,如果num[i] > LIS[top], 那么LIS[++top] = num[i]; dp[i] = top;如果num[i] == LIS[top],那么dp[i] = top; 如果num[i] < LIS[top], 那么二分查找到某个等于或者大于num[i]的最接近的值的位置(第k个),dp[i] = k - 1; LIS[k] = num[i];

题目:UVA - 10534Wavio Sequence

伪代码
    dp[maxn], LIS[maxn], s[maxn];top = 0;LIS[top++] = s[1];int maxlen = 1;for i in range(2, len):if s[i] > LIS[top]:LIS[++top] = s[i];dp[i] = top + 1;else if s[i] == LIS[top]:dp[i] = top + 1;else:k = lower_bound(LIS.begin(), LIS.end(), s[i]) - LIS.beign();LIS[k] = s[i];dp[i] = k + 1;maxlen = max(maxlen, dp[i]);else:;return maxlen;
最长公共子序列O(n * logn)

要求串本身不会出现相同的数字或是字母。通过对第一个字符串进行映射(递增的顺序),然后第二个字符串依照上面的第一个字符串等价映射,这样就把问题从LCS转化成LIS。例如:
串1: 2 4 3 5 6
映射:1 2 3 4 5
串2: 3 2 6 8 10
等价映射:3 1 5 0 0

题目:uva10635Prince and Princess


这篇关于LIS(最长递增子序列)和LCS(最长公共子序列)的总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1101399

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

poj3261(可重复k次的最长子串)

题意:可重复k次的最长子串 解题思路:求所有区间[x,x+k-1]中的最小值的最大值。求sa时间复杂度Nlog(N),求最值时间复杂度N*N,但实际复杂度很低。题目数据也比较水,不然估计过不了。 代码入下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring

poj1330(LCA最近公共祖先)

题意:求最近公共祖先 思路:之前学习了树链剖分,然后我就用树链剖分的一小部分知识就可以解这个题目了,记录每个结点的fa和depth。然后查找时,每次将depth大的结点往上走直到x = y。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

uva 10131 最长子序列

题意: 给大象的体重和智商,求体重按从大到小,智商从高到低的最长子序列,并输出路径。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vect

uva 10066 LCS

题意: 最长公共子序列。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter