最长公共子序列

最长公共子序列

北战南征 提交于 2019-12-04 13:15:50
最长公共子序列 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,a[1001],b[1001]; int f[1001][1001]; int main() { cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=m;i++) cin>>b[i]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { f[i][j]=max(f[i-1][j],f[i][j-1]); if(a[i]==b[j]) f[i][j]=max(f[i][j],f[i-1][j-1]+1); } cout<<f[n][m]<<endl; return 0; } 来源: https://www.cnblogs.com/Hawking-llfz/p/11864211.html

LCIS(最长公共上升子序列)

为君一笑 提交于 2019-12-04 11:49:44
参考题解chennachuan_2004 /* #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int MAXN=5005; int N, M, A[MAXN], B[MAXN]; int f[MAXN][MAXN], ansj=0, lcis[MAXN][MAXN]; void LCIS(); void Input(); int main() { Input(); LCIS(); printf("%d\n",f[N][ansj]); for (int p=1; p<=f[N][ansj]; p++) printf("%d ",lcis[ansj][p]); puts(""); return 0; } void LCIS() { memset (f, 0, sizeof(f)); memset (lcis, 0, sizeof(lcis)); for (int i=1; i<=N; i++) { for (int j=1,k=0; j<=M; j++) { if (A[i] == B[j]) { f[i][j] = f[i-1][k]+1; for (int p=1; p<=f[i-1][k]; p++) lcis[j]

P1439 【模板】最长公共子序列

删除回忆录丶 提交于 2019-12-03 04:49:38
P1439 【模板】最长公共子序列 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e5+5; 4 int id[maxn]; 5 vector<int> ve; 6 int main() { 7 int n; scanf("%d",&n); 8 for (int i = 1; i <= n; ++i) { 9 int x; scanf("%d",&x); 10 id[x] = i; 11 } 12 for (int i = 1; i <= n; ++i) { 13 int x; scanf("%d",&x); 14 x = id[x]; 15 if (i == 1) ve.push_back(x); 16 else { 17 if (x > ve[ve.size()-1]) ve.push_back(x); 18 else { 19 ve[lower_bound(ve.begin(),ve.end(),x)-ve.begin()] = x; 20 } 21 } 22 } 23 printf("%d",ve.size()); 24 return 0; 25 } 来源: https://www.cnblogs.com/wstong/p/11778460.html

#问题求解与编程# 实验七 E 最长公共子序列

匿名 (未验证) 提交于 2019-12-03 00:26:01
最长公共子序列 描述 ben和mei在做一个项目。现在他们遇到了一个难题,需要你的帮助。问题可以抽象为,给定两个整型数串,求它们的最长公共子序列。最长公共子序列的定义是,一个数列 S ,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。 输入 输入包含多组测试数据,每组数据首先包含一个N和一个M,分别表示两个整型串的长度,接下来是两行数据,分别有N个和M个整数(0<N<1000, 0<M<1000)。 输出 对每组数据,请输出它们最长公共子序列的长度。 复制 7 8 1 3 4 6 7 5 4 1 6 3 4 8 7 5 6 8 7 1 2 3 1 2 3 1 2 1 3 2 3 2 3 2 样例输出1 5 6 提示 样例一的最长公共子序列:1 3 4 7 5,长度为5 样例二的最长公共子序列:1 2 3 2 3 2,长度为6 ―――――――――――――――――――――――――――――――――――――――――――――――――――― 不会 但是知道是动态规划问题 上标程慢慢理解吧 现在还是没太搞懂 动态背包问题 按照这张图去理解比较好~: #include<cstdio> #include<cstring> #include<iostream> using namespace std; int dp[1010][1010];

最长公共子序列转化最长上升子序列 n log n做法

匿名 (未验证) 提交于 2019-12-03 00:22:01
题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列。 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列。 输出格式: 一个数,即最长公共子序列的长度 如题。 我们让 i d [ i ] i d [ i ] 为数字i在P1中出现的位置。 然后对于第二行出现的数字j,我们只需要知道它在第一行出现的位置,放在数组 d a t a d a t a 里面,让 d a t a [ i ] = i d [ P 2 [ j ] ] d a t a [ i ] = i d [ P 2 [ j ] ] ,求最长上升子序列即可。 这个正确性我不会证明。。。但是举例子一看确乎可以。。 #include<bits/stdc++.h> using namespace std; inline int read(){ int num= 0 ; char c= ' ' ; bool flag= true ; for (;c> '9' ||c< '0' ;c=getchar()) if (c== '-' ) flag= false ; for (;c>= '0' &&c<= '9' ;num=(num<< 3 )+(num<< 1 )+c- 48 ,c=getchar()); return flag ? num : -num; } const int

c++最长公共子序列

匿名 (未验证) 提交于 2019-12-03 00:11:01
Description Input 第一行:序列A的长度 第二行:给出序列A 第三行:序列B的长度 第四行:给出序列B 长度<=1000 Output 只有一行:表示最长的公共子序列的长度 Sample Input 6 1 6 2 5 4 7 7 0 1 2 5 5 2 7 Sample Output 4 Source #include < bits / stdc ++. h > using namespace std ; int f [ 1001 ][ 1001 ]; int n , m , a [ 1001 ], b [ 1001 ]; int main () { cin >> n ; for ( int i = 1 ; i <= n ; i ++) { scanf ( "%d" ,& a [ i ]); } cin >> m ; for ( int i = 1 ; i <= m ; i ++) { scanf ( "%d" ,& b [ i ]); } f [ 0 ][ 0 ] = 0 ; f [ 0 ][ 1 ] = 0 ; f [ 1 ][ 0 ] = 0 ; for ( int i = 1 ; i <= n ; i ++) { for ( int j = 1 ; j <= m ; j ++) { if ( a [ i ] == b [ j ]) { f [ i ][ j

LCS 求最长公共子序列

匿名 (未验证) 提交于 2019-12-03 00:02:01
最长公共子序列不需要字符连续出现和字串不同 //LCS 求最长公共子串模板题 Common Subsequence 描述 A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = <x1, x2, ..., xm> another sequence Z = <z1, z2, ..., zk> is a subsequence of X if there exists a strictly increasing sequence <i1, i2, ..., ik> of indices of X such that for all j = 1,2,...,k, xij = zj. For example, Z = <a, b, f, c> is a subsequence of X = <a, b, c, f, b, c> with index sequence <1, 2, 4, 6>. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X

P1439 【模板】最长公共子序列(DP)

匿名 (未验证) 提交于 2019-12-02 23:43:01
题目描述 给出1-n的两个排列P1和P2,求它们的最长公共子序列。 输入输出格式 输入格式: 第一行是一个数n, 接下来两行,每行为n个数,为自然数1-n的一个排列。 输出格式: 一个数,即最长公共子序列的长度 输入输出样例 输入样例#1: 复制 5 3 2 1 4 5 1 2 3 4 5 输出样例#1: 复制 3 说明 【数据规模】 对于50%的数据,n≤1000 对于100%的数据,n≤100000 题解: 刚开始看题以为是一道简单的LCS,但是一看数据到达的十万就知道不能用常规的LCS,之后一直在想新的方法,结果就是没有结果<_> 参考博客:https://pks-loving.blog.luogu.org/junior-dynamic-programming-dong-tai-gui-hua-chu-bu-ge-zhong-zi-xu-lie(里面还讲了一些LIS的nlogn和路径记录) 主要是没有对题目给出的条件充分利用,题目上说给出的两个序列中的数的范围是【1---n】,不能重复,只是第一个序列中的那个数在第二个序列中的位置不一样罢了 所以我们只需要找出来第一个序列中的每个位置得数在第二个序列中的位置就可以了 为什么呢? 因为我们要求的是两个序列的LCS,所以我们要求出来第一个序列与第二个序列最长相似部分,我们把第一个序列的每个数转化成在第二个序列的位置

51nod 1006 最长公共子序列Lcs【DP】

匿名 (未验证) 提交于 2019-12-02 23:34:01
1006 最长公共子序列Lcs 1 秒 / 131,072 KB / 基础题 问题 给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最长的子序列。 输入 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000) 输出 输出最长的子序列,如果有多个,随意输出1个。 输入样例 abcicba abdkscab 输出样例 abca 题目。 解题时卡在没有想到好的方法输出路径(我用DFS一直错)。办法:记录路径。 如何记录路径:记录此状态的上一步,或者说记录当前是如何由上一步得出的。即:方向。 #include < cstdio > #include < string > #include < iostream > using namespace std ; string a , b , ans ; const int Max_num = 1e3 + 17 ; int dp [ Max_num ] [ Max_num ] , book [ Max_num ] [ Max_num ] ; //book[][]记录方向 int main ( ) { cin >> a >> b ; int la = a . length ( ) ,

动态规划之最长公共子序列

匿名 (未验证) 提交于 2019-12-02 23:34:01
最长公共子序列,顾名思义,就是给定两个序列,求出其中长度最长的共有的子序列。如,给定1,2,4,5,6和2,4,5 显然2,4,5是最长的共有序列。 那么,如何分析此类问题呢? 老方法,我们仍要找出前后状态之间的联系。显然,这是给定了两个序列,那么肯定是开了一个二维 的数组,进行二维的遍历。 假设,a[n],b[m]是给定的序列。如果遍历的过程中,a[i]=b[j],那么显然这一状态等于前一状态加1,此时前一状态是dp[i-1][j-1]。 那如果a[i]!=b[j]的话,那么此时的最长值,是前一状态的最长值,所以这次我们得寻找前一状态。不加思考的话,我们很容易的得出前一状态是dp[i-1][j-1]。 其实这样是不对的,因为此状态与前一状态相比,b数组向后遍历了一位,那这引发的变化,使得前一状态有两组组合,即dp[i-1][j],dp[i][j-1],求出其中的最大,就可得到最终的结果。代码如下: #include <iostream> using namespace std ; int main (){ int n , m ; cin << n ; cin << m ; int a [ n ], b [ m ]; for ( int i = 1 ; i <= n ; i ++){ cin << a [ i ]; } for ( int i = 1 ; i <= m ; i ++