【模板】最长上升子序列及其优化

给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。

输入格式

第一行包含整数 N。

第二行包含 N 个整数,表示完整序列。

输出格式

输出一个整数,表示最大长度。

数据范围

1≤N≤1000,
−109≤数列中的数≤109

输入样例:

1
2
7
3 1 2 1 8 5 6

输出样例

1
4

模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010;

int n;
int a[N], f[N];

int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);

for (int i = 1; i <= n; i ++ )
{
f[i] = 1; // 只有a[i]一个数
for (int j = 1; j < i; j ++ )
if (a[j] < a[i])
f[i] = max(f[i], f[j] + 1);
}

int res = 0;
for (int i = 1; i <= n; i ++ ) res = max(res, f[i]);

printf("%d\n", res);

return 0;
}

改变数据范围

1≤N≤100000,
−109≤数列中的数≤109

image.png

模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 100010;

int n;
int a[N];
int q[N];

int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++) scanf("%d", &a[i]);

q[0] = -2e9; // 哨兵
int len = 0;
for (int i = 0; i < n; i ++)
{
int l = 0, r = len;
while(l < r)
{
int mid = l + r + 1 >> 1;
if (q[mid] < a[i]) l = mid;
else r = mid - 1;
}
len = max(len, r + 1);
q[r+1] = a[i];
}

printf("%d\n", len);

return 0;
}

【模板】最长上升子序列及其优化
https://piscesfinalizer.github.io/2021/05/14/【模板】最长上升子序列及其优化/
作者
PiscesFinalizer
发布于
2021年5月14日
许可协议