LIS(最长递增子序列)和LCS(最长公共子序列)的总结
2014-10-29 16:08
351 查看
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;
伪代码:
题目: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);
伪代码
题目: 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
伪代码
最长公共子序列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
最长公共子序列(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]; //init for 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最长递增子序列和最长公共子序列问题
- 【LIS和LCS】最长上升子序列和最长公共子序列
- 最长公共子序列LCS和最长单调递增子序列
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
- LCS(最长公共子序列)、LIS(最长上升子序列)、LCIS(最长公共上升子序列)
- 最长公共子序列(LCS)、最长递增子序列(LIS)、最长递增公共子序列(LICS)
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
- See LCS again 最长递增子序列到最长公共子序列的转化
- (DP6.1.4.1)UVA 111 History Grading(最长递增子序列LIS 的LCS 解法)
- LIS 最长递增子序列问题
- 【LCS,LIS】最长公共子序列、单调递增最长子序列
- poj 2533 (LIS 最长递增子序列)
- 动态规划-最长递增子序列/最长公共子序列/01背包问题
- 最长递增子序列问题的求解(LIS)
- 最长递增子序列LIS
- 动态规划 最长公共子序列 LCS,最长单独递增子序列,最长公共子串
- 合唱队形(LIS最长递增子序列) 解题过程
- dp之最长递增、公共子序列总结
- LIS 最长递增子序列
- 编程之美---求数组中最长递增子序列LIS