题目描述
朴素版上升子序列
import java.util.*;
public class Main {
static final int N = 1010;
static int[] f = new int[N], a = new int[N];
static int n;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int i = 1; i <= n; i++) a[i] = sc.nextInt();
for (int i = 1; i <= n; i++) {
f[i] = 1;
for (int j = i - 1; j >= 1; j--) {
if (a[j] < a[i]) {
f[i] = Math.max(f[i], f[j] + 1);
}
}
}
int res = 0;
for (int i = 1; i <= n; i++)
if (res < f[i]) res = f[i];
System.out.println(res);
}
}
贪心
$O(n^logn)$
下标从0开始
import java.util.*;
public class Main {
static final int N = 100010;
static int[] arr = new int[N], q = new int[N];
static int n;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
sc.nextLine();
String[] s = sc.nextLine().split(" ");
for (int i = 0; i < n; i++) arr[i] = Integer.parseInt(s[i]);
int len = 0;
q[0] = (int) -2e9;
for (int i = 0; i < n; i++) {
int l = 0, r = len;
while (l < r) {
int mid = l + r + 1 >> 1;
if (q[mid] < arr[i]) l = mid;
else r = mid - 1;
}
len = Math.max(len, l + 1);
q[l + 1] = arr[i];
}
System.out.println(len);
}
}
下标从1开始
import java.util.*;
public class Main {
static final int N = 100010;
static int[] arr = new int[N], q = new int[N];
static int n;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
sc.nextLine();
String[] s = sc.nextLine().split(" ");
for (int i = 1; i <= n; i++) arr[i] = Integer.parseInt(s[i - 1]);
int len = 0;
//q[i]表示长度为i的上升子序列的最小头结点:
//对于1 2 3 4:q[3]:长度为3的上升子序列的最小值即为3也就是q[i]=3
for (int i = 1; i <= n; i++) {
//寻找a[i]要插入的位置
int l = 0, r = len;
while (l < r) {
int mid = l + r + 1 >> 1;
if (q[mid] < arr[i]) l = mid;
else r = mid - 1;
}
len = Math.max(len, l + 1);
q[l + 1] = arr[i];
}
System.out.println(len);
}
}