最长公共子序列

牛客 最长公共子序列问题

点点圈 提交于 2019-11-28 04:52:34
题目链接: https://www.nowcoder.com/practice/4727c06b9ee9446cab2e859b4bb86bb8?tpId=101&tqId=33099&tPage=1&rp=1&ru=/ta/programmer-code-interview-guide&qru=/ta/programmer-code-interview-guide/question-ranking 题目大意   略。 分析   先求 LCS 的 dp 表,然后倒着求 LCS。 代码如下 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 5 #define Rep(i,n) for (int i = 0; i < (int)(n); ++i) 6 #define For(i,s,t) for (int i = (int)(s); i <= (int)(t); ++i) 7 #define rFor(i,t,s) for (int i = (int)(t); i >= (int)(s); --i) 8 #define ForLL(i, s, t) for (LL i = LL(s); i <=

poj(1458)(最长公共子序列)

◇◆丶佛笑我妖孽 提交于 2019-11-28 02:11:01
44 #include " iostream " 45 #define M 1000 // 适合数据量小的字符串,那么字符串长度过大时又如何处理?! 46 using namespace std; 47 int c[M][M]; 48 int Max( int a , int b) 49 { 50 return a > b ? a:b; 51 } 52 void LCD( char aa[], char bb[], int x, int y) // 核心 53 { 54 int i,j; 55 for (i = 0 ;i <= x;i ++ ) 56 c[i][ 0 ] = 0 ; 57 for (j = 0 ;j <= y;j ++ ) 58 c[ 0 ][j] = 0 ; 59 60 for (i = 1 ;i <= x;i ++ ) 61 for (j = 1 ;j <= y;j ++ ) 62 { 63 if (aa[i - 1 ] == bb[j - 1 ]) c[i][j] = c[i - 1 ][j - 1 ] + 1 ; // 将前一行前一列的值+1(即对角线上前一个点加1,目的是保证了所找到的字符串是最大的) 64 else c[i][j] = Max(c[i][j - 1 ],c[i - 1 ][j]); // 在不相等的情况下

动态规划

两盒软妹~` 提交于 2019-11-27 05:45:25
动态规划 算法总体思想 动态规划算法与分治法类似,其基本思想也是将 待求解问题分解成若干个子问题 。 但是经分解得到的 子问题往往不是互相独立 的。不同子问题的数目常常只有多项式量级。在用分治法求解时,有些子问题被重复计算了许多次。 如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。 动态规划基本步骤: (1)找出最优解的性质,并刻划其结构特征。 (2)递归地定义最优值。 (3)以自底向上的方式计算出最优值。 (4)根据计算最优值时得到的信息,构造最优解。 实例一、完全加括号的矩阵连乘积 问题可递归定义: (1)单个矩阵是完全加括号的; (2)矩阵连乘积A是完全加括号的 ,则A可表示为2个完全加括号的矩阵连乘积B和C的乘积并加括号,即 A = (BC)。 设有四个矩阵A,B,C,D它们的维数分别是: A = 50*10 , B = 10*40 , C = 40*30 , D = 30*5 总共有五中完全加括号的方式: 例如:((A(BC))D): 10 * 40 * 30 + 10 * 30 * 50 + 50 * 30 * 5 = 34500 给定矩阵{A1, A2, A3,..., An},其中Ai与A(i+1)是可乘的。i = 1,2,3, ..., n - 1。考察这n个矩阵的连乘积A1*A2*A3...An.

最长公共上升子序列

风流意气都作罢 提交于 2019-11-27 03:52:51
最长公共上升子序列 题目 提交记录 讨论 题解 视频讲解 熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目。 小沐沐先让奶牛研究了最长上升子序列,再让他们研究了最长公共子序列,现在又让他们研究最长公共上升子序列了。 小沐沐说,对于两个数列A和B,如果它们都包含一段位置不一定连续的数,且数值是严格递增的,那么称这一段数是两个数列的公共上升子序列,而所有的公共上升子序列中最长的就是最长公共上升子序列了。 奶牛半懂不懂,小沐沐要你来告诉奶牛什么是最长公共上升子序列。 不过,只要告诉奶牛它的长度就可以了。 数列A和B的长度均不超过3000。 输入格式 第一行包含一个整数N,表示数列A,B的长度。 第二行包含N个整数,表示数列A。 第三行包含N个整数,表示数列B。 输出格式 输出一个整数,表示最长公共子序列的长度。 数据范围 1 ≤ N ≤ 3000 1≤N≤3000,序列中的数字均不超过 2 31 − 1 231−1 输入样例: 4 2 2 1 3 2 1 2 3 输出样例: 2https://wenku.baidu.com/view/3e78f223aaea998fcc220ea0.html 二维 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 #include

最长公共子序列

元气小坏坏 提交于 2019-11-27 03:43:24
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 #include <vector> 6 using namespace std; 7 8 typedef long long ll; 9 ll n; 10 ll arr[3005],brr[3005]; 11 ll dp[3005][3005]; 12 ll maxx; 13 14 15 int main(){ 16 ios::sync_with_stdio(false); 17 cin>>n; 18 maxx=0; 19 for(int i=1;i<=n;i++) cin>>arr[i]; 20 for(int i=1;i<=n;i++) cin>>brr[i]; 21 for(int i=1;i<=n;i++){ 22 for(int j=1;j<=n;j++){ 23 if(arr[i]==brr[j]) dp[i][j]=dp[i-1][j-1]+1; 24 else{ 25 dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 26 } 27 } 28 } 29 cout << dp[n][n] << endl; 30 return 0; 31 } View Code 来源:

最长公共子序列c++实现

走远了吗. 提交于 2019-11-27 00:23:33
最长公共子序列 给定两个字符串S1和S2,求两个字符串的最长公共子序列的长度。 输入样例 ABCD AEBD 输出样例 3 解释 S1和S2的最长公共子序列为ABD,长度为3 思路 动态规划 L C S ( m , n ) LCS(m ,n) L C S ( m , n ) 表示 S 1 [ 0... m ] S1[0...m] S 1 [ 0 . . . m ] 和 S 2 [ 0... n ] S2[0...n] S 2 [ 0 . . . n ] 的最长公共子序列的长度 S 1 [ m ] = = S 2 [ n ] : L C S ( m , n ) = 1 + L C S ( m − 1 , n − 1 ) S1[m] == S2[n]: LCS(m, n) = 1 + LCS(m - 1, n - 1) S 1 [ m ] = = S 2 [ n ] : L C S ( m , n ) = 1 + L C S ( m − 1 , n − 1 ) S 1 [ m ] ! = S 2 [ n ] : L C S ( m , n ) = m a x ( L C S ( m − 1 , n ) , L C S ( m , n − 1 ) ) S1[m] != S2[n]: LCS(m, n) = max(LCS(m - 1, n), LCS(m, n - 1)) S 1 [ m

最长公共子序列

帅比萌擦擦* 提交于 2019-11-26 22:31:19
给定两个字符串,求解这两个字符串的最长公共子序列(Longest Common Sequence)。比如字符串1:BDCABA;字符串2:ABCBDAB 则这两个字符串的最长公共子序列长度为4,最长公共子序列是:BCBA 代码: def findLCS(A, n, B, m): # write code here record = 0 maxNum = 0 result = [] for i in range(n): for j in range(m): if A[i] == B[j]: if A[i] not in result: record += 1 # print(A[i]) result.append(A[i]) if maxNum < record: maxNum = record return maxNum,"".join(result) if __name__ == "__main__": A = "BDCABA" n = 6 B = "ABCBDAB" m =7 print(findLCS(A, n, B, m)) 来源: https://www.cnblogs.com/ivyharding/p/11334023.html

对最长公共子序列(LCS)等一系列DP问题的研究

北战南征 提交于 2019-11-26 17:59:49
LIS问题: 设 \(f[i]\) 为以 \(a[i]\) 结尾的最长上升子序列长度,有: \[f[i]=f[j]+1(j<i&&a[j]<a[i])\] 可以用树状数组优化至 \(O(nlogn)\) 基于排列的LCS问题( \(a,b\) 均为排列,即一个元素不会出现多次): 设 \(pos_i\) 为 \(a_i\) 在 \(b\) 中出现的位置,即 \(a_i=b_pos_i\) 。 \(a\) 的一个子序列 \(a_p_1,a_p_2,...,a_p_m\) 是 \(a,b\) 的公共子序列等价于 \(pos_p_1<pos_p_2<...<pos_p_m\) 求一个LIS即可。 一般LCS问题: 经典解法: 设 \(f[i][j]\) 表示只考虑 \(a\) 中前 \(i\) 个, \(b\) 中前 \(j\) 个的最长公共子序列长度,有: \[f[i][j]=\left\{ \begin{aligned} & f[i-1][j-1] & a[i]=b[j]\\ & max(f[i-1][j],f[i][j-1]) & a[i]!=b[j]\\ \end{aligned} \right.\] 十分简单,但是还有一种稍微复杂但是拓展性更高的做法: 设$f[i][j]$表示只考虑$a$中前$i$个,$b$中前$j$个并且$b_j$已经和$a_1,...,a_i

最长公共子序列(LCS)

半城伤御伤魂 提交于 2019-11-26 04:17:39
最长公共子序列(LCS) LCS是Longest Common Subsequence的缩写,即最长公共子序列。一个序列,如果是两个或多个已知序列的子序列,且是所有子序列中最长的,则为最长公共子序列。比如,对于char x[]=“aabcd”;有顺序且相互相邻的aabc是其子序列,有顺序但是不相邻的abc也是其公共子序列。即,只要得出序列中各个元素属于所给出的数列,就是子序列。再加上char y[]=“12abcabcd”;对比出才可以得出最长公共子序列abcd。 代码: # include <bits/stdc++.h> using namespace std ; const int maxm = 1e3 + 5 ; int dp [ maxm ] [ maxm ] ; int main ( ) { string s1 , s2 ; cin >> s1 >> s2 ; for ( int i = 1 ; i <= s1 . length ( ) ; i ++ ) { for ( int j = 1 ; j <= s2 . length ( ) ; j ++ ) { if ( s1 [ i - 1 ] == s2 [ j - 1 ] ) dp [ i ] [ j ] = dp [ i - 1 ] [ j - 1 ] + 1 ; dp [ i ] [ j ] = max ( dp [