转化为最长递增子序列问题,不过需要绝对递增(等于要处理好)
O(n log n)
O(n)
import java.util.Arrays; import java.util.Scanner; class Ev{ public int l; public int w; } public class Main { public static Scanner sc = new Scanner(System.in); public static void main(String[] args) { int n = sc.nextInt(); Ev[] arr = new Ev[n]; for(int i = 0; i < n; i ++){ arr[i] = new Ev(); arr[i].l = sc.nextInt(); arr[i].w = sc.nextInt(); } Arrays.sort(arr, (a, b)->{ if(a.l < b.l){ return -1; }else if(a.l == b.l){ if(a.w < b.w){ return -1; }else if(a.w == b.w){ return 0; } } return 1; }); int[] newArr = new int[n]; for(int i=0;i<n;i++){ newArr[i] = arr[i].w; } int ans = getMax(newArr, n); System.out.println(ans); } // 最左边大于等于val的数 static int bsearch(int[] ends, int left, int right, int val){ if(val <= ends[left]){ return -2; } if(val > ends[right]){ return -1; } if(val == ends[right]){ return -3; } while (left <= right){ int mid = (left + right) / 2; if(ends[mid] <= val){ left = mid + 1; }else { right = mid - 1; } } return left; } static int getMax(int[] arr, int n){ // ends[b] = c 表示遍历到目前为止 长度为b+1的递增序列中,最小的结尾数 c // ends[] 是一个递增的数组,适合二分法 int[] ends = new int[n]; // dp[i] 以 i 位置结束的最长递增长度 int[] dp = new int[n]; dp[0] = 1; ends[0] = arr[0]; // 有效区域[0, right]; right + 1 为 最长递增 int right = 0; for(int i=1;i<n;i++){ int pos = bsearch(ends,0, right, arr[i]); if(pos == -1){ // arr[i] 当前最大 right = right + 1; ends[right] = arr[i]; dp[i] = right + 1; }else if(pos == -2){ ends[0] = arr[i]; dp[i] = 1; }else if(pos == -3){ dp[i] = right; }else{ right = Math.max(right, pos); ends[pos] = arr[i]; dp[i] = pos + 1; } } int maxLen = right + 1; return maxLen; } } /* 9 3 4 2 3 4 5 1 3 2 2 3 6 1 2 3 2 2 4 4 */
import java.util.Arrays; import java.util.Scanner; class Ev{ public int l; public int w; } public class Main { public static Scanner sc = new Scanner(System.in); public static void main(String[] args) { int n = sc.nextInt(); Ev[] arr = new Ev[n]; for(int i = 0; i < n; i ++){ arr[i] = new Ev(); arr[i].l = sc.nextInt(); arr[i].w = sc.nextInt(); } Arrays.sort(arr, (a, b)->{ if(a.l < b.l){ return -1; }else if(a.l == b.l){ if(a.w < b.w){ return -1; }else if(a.w == b.w){ return 0; } } return 1; }); int[] dpPre = new int[n]; int[] dp = new int[n]; for(int i=0;i<n;i++){ dp[i] = 1; dpPre[i] = -1; } int ans = 0; for(int i=1;i<n;i++){ for(int j=0;j<i;j++){ if(arr[j].l < arr[i].l && arr[j].w < arr[i].w){ if(dp[j] + 1 > dp[i]) { dp[i] = dp[j] + 1; dpPre[i] = j; } if(dp[i] > ans){ ans = dp[i]; } } } } System.out.println(ans); } } /* 9 3 4 2 3 4 5 1 3 2 2 3 6 1 2 3 2 2 4 4 */