注意事项:
建议先理解基础版的写法:java—线性dp—最长上升子序列的长度1
题目:
给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少
第一行包含整数 N
第二行包含 N 个整数,表示完整序列
输出一个整数,表示最大长度
数据范围
1 ≤ N ≤ 100000,
−10e9 ≤ 数列中的数 ≤ 10e9
输入:
7
3 1 2 1 8 5 6
输出:
4
public class 线性dp_最长上升子序列2 {
public static int N = 10, n;
public static int[] a = new int[N];
public static Scanner in = new Scanner(System.in);
public static void main(String[] args) {
//读入
n = in.nextInt();
for (int i = 0; i<n; i++) a[i] = in.nextInt();
base();
}
public static void base() {
int[] q = new int[N];
int len = 0;
//遍历每个元素a[i],使用"向右"查找的二分来找到q中最后一个比a[i]小的值的下标r,将其后一位r+1替换为当前值
for (int i = 0; i<n; i++) {
int l = 0, r = len;
while (l < r) {
int mid = (l+r+1) / 2;
//这里对二分的模板做了一点点微调,正常应该是<=但这里用的是<
//因为要找到必须小于a[i]的值的下标r,更新r+1才能保证单调队列的绝对上升
if (q[mid] < a[i]) l = mid;
else r = mid - 1;
}
//不关心q内的元素到底是什么,只要保证size(子序列长度)最大即可
len = Math.max(len, r + 1);
q[r + 1] = a[i];
}
System.out.println(len);
}
}
思路:
求出严格单调的上升队列即可,不需要关心其中到底有什么元素,但这也就导致这种方法无法得到这个最长上升队列,如果想得到还是用这种方法较好:java—线性dp—拿到最长上升子序列
声明:
算法思路来源为y总,详细请见https://www.acwing.com/
本文仅用作学习记录和交流