简洁的一家设计公司网站作品展示网页模板html5+css3全站下载视频运营管理平台
最长公共子序列(LCS)(1)
题目描述
给出1-n的两个排列P1和P2,求它们的最长公共子序列。
输入
第一行是一个数n;(n是5~1000之间的整数)数据范围小,可以用二维数组dp
接下来两行,每行为n个数,为自然数1-n的一个排列(1-n的排列每行的数据都是1-n之间的数,但顺序可能不同,比如1-5的排列可以是:1 2 3 4 5,也可以是2 5 4 3 1)。
输出
一个整数,即最长公共子序列的长度。
样例输入
5
3 2 1 4 5
1 2 3 4 5
样例输出
3
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan=new Scanner(System.in);int n=scan.nextInt();int []a=new int[n+1];int []b=new int[n+1];int [][] dp=new int[n+1][n+1];for(int i=1;i<=n;i++){a[i]=scan.nextInt();}for(int i=1;i<=n;i++){b[i]=scan.nextInt();}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(a[i]==b[j]){dp[i][j]=dp[i-1][j-1]+1;}else{dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);}}}System.out.println(dp[n][n]);}
}
最长公共子序列(LCS)(2)
题目描述
给出1-n的两个排列P1和P2,求它们的最长公共子序列。
和最长公共子序列(LCS)(1)问题不同的是,本题的n在5-100000之间。数据范围大,要用映射的做法把问题转化为求最长递增子序列的长度
输入
第一行是一个数n;(n是5-100000之间的整数)
接下来两行,每行为n个数,为自然数1-n的一个排列(1-n的排列每行的数据都是1-n之间的数,但顺序可能不同,比如1-5的排列可以是:1 2 3 4 5,也可以是2 5 4 3 1)。
输出
一个整数,即最长公共子序列的长度。
样例输入
5
3 2 1 4 5
1 2 3 4 5
样例输出
3
提示
对于50%的数据,n≤1000
对于100%的数据,n≤100000
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan=new Scanner(System.in);int n=scan.nextInt();int[] p1=new int[n];int[] p2=new int[n];for(int i=0;i<n;i++){p1[i]=scan.nextInt();}for(int i=0;i<n;i++){p2[i]=scan.nextInt();}//映射int[] pos=new int[n+1];for(int i=0;i<n;i++){pos[p2[i]]=i;}int[] nums=new int[n+1]; //[2,1,0,3,4]for(int i=0;i<n;i++){nums[i]=pos[p1[i]];}//求nums的最长递增子序列int[] tails=new int[n];int len=0;for(int i=0;i<n;i++){int num=nums[i];int left=0;int right=len-1;int insertpos=len;while (left<=right){int mid=left+(right-left)/2;if(tails[mid]<num){left=mid+1;}else{insertpos=mid;right=mid-1;}}tails[insertpos]=num;if(insertpos==len){len++;}}System.out.println(len);}
}