AcWing 272. 最长公共上升子序列-java版本
原题链接
中等
作者:
莫得感情的刷题机器
,
2020-08-20 15:14:44
,
所有人可见
,
阅读 455
/**
* 定义集合和属性f(i,j):表示a的0-i和b的0-j的序列组成且以b(j)结尾的最长公共上升子序列的最大长度。
* 划分集合:如果a(i)不在最长公共子序列和a(i)在(a[i]在的情况有可能没有)
* a(i)不在最长公共上升子序列:f(i-1,j)
* a(i)在最长公共上升子序列,此时必须保证a(i)=b[j],:此时f(i,j)=max{f(i-1,j-1),f(i-1,j-2)...f(i-1,1)}+1
* (上面max里面的每个元素存在有个前提,就是一定要b(k)<b[j],且这种情况需要比较的时候一定是a(i)=b(j)的时候
* 所以就是b(k)<a(i),所以我们可以在遍历到j的同时就可以求出b(k)中的最大值。
*/
import java.util.*;
public class Main{
public static void main(String [] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int [] a=new int [n+1];
int [] b=new int[n+1];
int [][] f=new int[n+1][n+1];
for(int i=1;i<=n;i++) a[i]=sc.nextInt();
for(int i=1;i<=n;i++) b[i]=sc.nextInt();
for(int i=1;i<=n;i++){
int maxv=0;//b(k)中的最大值,初始为0,如果找不到满足的一定就是0,然后和1相加得到当前f(i,j).
for(int j=1;j<=n;j++){
f[i][j]=f[i-1][j];//a[i]不在最长公共上升子序列
if(a[i]==b[j]) f[i][j]=Math.max(maxv+1,f[i][j]);
if(b[j]<a[i]) maxv=Math.max(maxv,f[i][j]);
}
}
int res=0;
for(int i=1;i<=n;i++) res=Math.max(res,f[n][i]);//因为b[<n,i]<b[n,i],所以只需要遍历b[n,i]
System.out.println(res);
}
}