小红有两个长度为n的排列A和B。每个排列由[1,n]数组成,且里面的数字都是不同的。
现在要找到一个新的序列C,要求这个新序列中任意两个位置(i,j)满足:
如果在A数组中C[i]这个数在C[j]的后面,那么在B数组中需要C[i]这个数在C[j]的前面。
请问C序列的长度最长为多少呢?
小红有两个长度为n的排列A和B。每个排列由[1,n]数组成,且里面的数字都是不同的。
现在要找到一个新的序列C,要求这个新序列中任意两个位置(i,j)满足:
如果在A数组中C[i]这个数在C[j]的后面,那么在B数组中需要C[i]这个数在C[j]的前面。
请问C序列的长度最长为多少呢?
第一行一个整数,表示N。
第二行N个整数,表示A序列。
第三行N个整数,表示B序列。
满足:N<=50000
输出最大的长度
5 1 2 4 3 5 5 2 3 4 1
4
最长的C为1,3,4,5
import java.util.*;
class Main {
// public static int first(int[] a,int[] b){
// int[][] dp =new int[a.length+1][a.length+1];
// for(int i=1;i<=a.length;i++){
// for(int j=1;j<=a.length;j++){
// if(a[i-1]==b[j-1])
// dp[i][j] =dp[i-1][j-1]+1;
// else
// dp[i][j] =Math.max(dp[i-1][j],dp[i][j-1]);
// }
// }
// return dp[a.length][a.length];
// }
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = in.nextInt();
int[] arr1 = new int[num];
int[] arr2 = new int[num];
int[] map = new int[num + 1];
int[] need = new int[num];
for (int i = 0; i < num; i++) {
arr1[i] = in.nextInt();
map[arr1[i]] = i;
}
for (int i = 0; i < num; i++) {
arr2[i] = in.nextInt();
need[i] = map[arr2[i]];
}
// System.out.println(Arrays.toString(need));
List<Integer> dp = new ArrayList<>();
dp.add(need[0]);
for (int i = 1; i < num; i++) {
if (need[i] < dp.get(dp.size() - 1))dp.add(need[i]);
else {
int bound = Collections.
binarySearch(dp, need[i], (a, b)->b - a);
//System.out.println(-bound-1);
int index = -bound - 1;
dp.set(index,need[i]);
}
}
System.out.println(dp.size());
}
} import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scn=new Scanner(System.in);
while(scn.hasNextInt()){
int n=scn.nextInt();
int[] a=new int[n];
int[] b=new int[n];
for(int i=0;i<n;i++) a[i]=scn.nextInt();
for(int i=0;i<n;i++) b[n-1-i]=scn.nextInt();
int[][] dp=new int[2][n+1];
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dp[1][j]=a[i-1]==b[j-1]?dp[0][j-1]+1:Math.max(dp[0][j],dp[1][j-1]);
}
int[] temp=dp[0];
dp[0]=dp[1];
dp[1]=temp;
}
System.out.println(dp[0][n]);
break;
}
}
} import java.util.*;
public class Main{
public static void main(String []args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
HashMap<Integer,Integer> hs = new HashMap<>();
int[] index = new int[n];
for(int i = 0;i < n;i++){
hs.put(sc.nextInt(),i);
}
// 通过序列值映射下标
for(int i = 0;i < n;i++){
index[i] = (int)hs.get(sc.nextInt());
}
System.out.println(getSequence(index, n));
}
// 查找存储下标的数组最长降序子序列长度
public static int getSequence(int[] arr, int num){
// 考虑边界情况
if(num == 2)
return arr[0] > arr[1]?2:1;
else if(num == 1)
return 1;
// 新建一个数组存储降序子序列
int r = 0;// 记录des数组的下标位置
int[] des = new int[num];
des[r] = arr[r];
for(int i = 1;i < num;i++){
if(arr[i] < des[r]){
des[++r] = arr[i];
}else{
// r到达某一位置时,不是降序的
branching(des, r, arr[i]);
}
}
return r + 1;
}
// 对子序列进行分支
public static void branching(int[] des, int r, int curr){
// 边界条件
if(des[0] < curr){
des[0]= curr;
return;
}
if(r == 1){
des[0] = des[0] > curr ? des[0] : curr;
//return;// 不需要return
}
// 分支策略
int l = 0;
int m = 0;
while(r - 1 > l){
m = (r + l) / 2;
if(des[m] > curr)
l = m;
else
r = m;
}
des[r] = curr;
}
}