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;

伪代码:
  1. dp[maxn1][maxn2];
  2. s1[maxn1],s2[maxn2];
  3. p[maxn1][maxn2][2];
  4. //init
  5. for i in range(0, len1):
  6. dp[i][0] = 0;
  7. else:;
  8. for i in range(0, len2):
  9. dp[0][i] = 0;
  10. else:;
  11. for i in range(1, len1):
  12. for j in range(1, len2):
  13. if s1[i] == s2[j]:
  14. dp[i][j] = dp[i - 1][j - 1] + 1;
  15. p[i][j][0] = i - 1;
  16. p[i][j][1] = j - 1;
  17. else:
  18. if dp[i - 1][j] > dp[i][j - 1]:
  19. dp[i][j] = dp[i - 1][j];
  20. p[i][j][0] = i - 1;
  21. p[i][j][1] = j;
  22. else:
  23. dp[i][j] = dp[i][j - 1];
  24. p[i][j][0] = i;
  25. p[i][j][1] = j - 1;
  26. else:;
  27. else:;
  28. return dp[len1][len2];
  29. //path 非递归
  30. function print_path(len1, len2):
  31. if (dp[len1][len2] == 0)
  32. return;
  33. printf_path(p[len1][len2][0], p[len1][len2][1]);
  34. if s1[len1] == s2[len2]:
  35. printf:s1[len1];
  36. 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);

伪代码
  1. s[maxn],dp[maxn];
  2. for i in range(1, len):
  3. dp[i] = 1;
  4. int maxlen = 1;
  5. for i in range(2, len):
  6. for j range(1, i - 1):
  7. if s[i] > s[j]:
  8. dp[i] = Max(dp[i], dp[j] + 1);
  9. else:
  10. maxlen = max(maxlen, dp[i]);
  11. else:;
  12. return maxlen;
  13. //path递归
  14. function print_path(maxlen):
  15. if maxlen == 0:return;
  16. for i in range(1, len):
  17. if dp[i] == maxlen:
  18. print_path(maxlen - 1);
  19. printf:s[i];
  20. 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

伪代码
  1. dp[maxn], LIS[maxn], s[maxn];
  2. top = 0;
  3. LIS[top++] = s[1];
  4. int maxlen = 1;
  5. for i in range(2, len):
  6. if s[i] > LIS[top]:
  7. LIS[++top] = s[i];
  8. dp[i] = top + 1;
  9. else if s[i] == LIS[top]:
  10. dp[i] = top + 1;
  11. else:
  12. k = lower_bound(LIS.begin(), LIS.end(), s[i]) - LIS.beign();
  13. LIS[k] = s[i];
  14. dp[i] = k + 1;
  15. maxlen = max(maxlen, dp[i]);
  16. else:;
  17. 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(最长公共子)总结的更多相关文章

  1. [LeetCode] Binary Tree Longest Consecutive Sequence II 二叉树最长连续序列之二

    Given a binary tree, you need to find the length of Longest Consecutive Path in Binary Tree. Especia ...

  2. 最长上升序列 LCS LIS

    子序列问题 (一)一个序列中的最长上升子序列(LISLIS) n2做法 直接dp即可: ;i<=n;i++) { dp[i]=;//初始化 ;j<i;j++)//枚举i之前的每一个j ) ...

  3. 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列

    出处 http://segmentfault.com/blog/exploring/ 本章讲解:1. LCS(最长公共子序列)O(n^2)的时间复杂度,O(n^2)的空间复杂度:2. 与之类似但不同的 ...

  4. (LIS)最长上升序列(DP+二分优化)

    求一个数列的最长上升序列 动态规划法:O(n^2) //DP int LIS(int a[], int n) { int DP[n]; int Cnt=-1; memset(DP, 0, sizeof ...

  5. XHXJ's LIS HDU - 4352 最长递增序列&数位dp

    代码+题解: 1 //题意: 2 //输出在区间[li,ri]中有多少个数是满足这个要求的:这个数的最长递增序列长度等于k 3 //注意是最长序列,可不是子串.子序列是不用紧挨着的 4 // 5 // ...

  6. HDU-4521 小明系列问题——小明序列 间隔限制最长上升子序列

    题意:给定一个长度为N的序列,现在要求给出一个最长的序列满足序列中的元素严格上升并且相邻两个数字的下标间隔要严格大于d. 分析: 1.线段树 由于给定的元素的取值范围为0-10^5,因此维护一棵线段树 ...

  7. LCS最长公共子序列(最优线性时间O(n))

    这篇日志主要为了记录这几天的学习成果. 最长公共子序列根据要不要求子序列连续分两种情况. 只考虑两个串的情况,假设两个串长度均为n. 一,子序列不要求连续. (1)动态规划(O(n*n)) (转自:h ...

  8. LCS最长公共子序列

    问题:最长公共子序列不要求所求得的字符串在所给字符串中是连续的,如输入两个字符串ABCBDAB和BDCABA,字符串BCBA和BDAB都是他们的公共最长子序列 该问题属于动态规划问题 解答:设序列X= ...

  9. POJ 2250(LCS最长公共子序列)

    compromise Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u   Descri ...

随机推荐

  1. Microsoft Win32 Programmer's Reference.chm

    实在是太棒了,感谢这位网友: http://download.csdn.net/detail/tgyd6800/9632351

  2. 网站遭遇DDOS简易处理

    网站遭遇DDOS攻击 netstat -an | grep ESTABLISHED 我们看到有大量的链接存在着,并且都是ESTABLISHED状态 for i in `netstat -an | gr ...

  3. Java多线程-实例解析

    Java多线程实例 3种实现方法Java中的多线程有三种实现方式:1.继承Thread类,重写run方法.Thread本质上也是一个实现了Runnable的实例,他代表一个线程的实例,并且启动线程的唯 ...

  4. Qt控件精讲一:按钮

    原地址:http://blog.csdn.net/yuxikuo_1/article/details/17397109 Qt Creater提供6种Button控件.如图1. Button控件介绍 控 ...

  5. Delphi中运行时改变panel的位置及大小(通过wm_SysCommand来实现)

    procedure TForm1.pnl1MouseDown(Sender: TObject; Button: TMouseButton;  Shift: TShiftState; X, Y: Int ...

  6. c# winform 让Form去掉系统自带的关闭

    在桌面系统时我们有时候想把winform 自带的关闭按钮和最大化最小化都去掉,我遇到了类似的情况,在网上一查也有很多答案,但是最后找到了一个最简单的答案,一句话的事,今天记录一下,就是让大家都简单的实 ...

  7. SQL逆向工程

    话说有个现成的SQL数据库,四十来张表,每张表多的几十的字段,少的十几个字段.老板说为了下一步大家好好利用这个数据库中的数据,让你研究一下该数据库中的所有的表和字段之间的联系.这是一个什么性质的工作, ...

  8. Servlet的学习之Session(1)

    在学习完了Servlet中的Cookie技术后,我们再来学习另一个能保存会话数据的技术——Session. Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其 ...

  9. delphi中一切皆指针

    unit Unit1; interface uses  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Form ...

  10. ajax获取的全部是object,我要获取的是json

     编程语言 ---------------------------------------------前台: $(document).ready(function() {  var data= []; ...