Solution
解法一
其实就是暴力求 LIS
。
只是记录一下
O
(
n
log
n
)
O(n\log n)
O(nlogn) 求 LIS
的算法。
解法二
博主太蒻,虽咕但下次一定。
Code
解法一
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 6005;
int n, w[N], cnt, nxt[N << 1], to[N << 1], head[N], ans, f[N];
int read() {
int x = 0, f = 1; char s;
while((s = getchar()) > '9' || s < '0') if(s == '-') f = -1;
while(s >= '0' && s <= '9') x = (x << 1) + (x << 3) + (s ^ 48), s = getchar();
return x * f;
}
void addEdge(const int u, const int v) {
nxt[++ cnt] = head[u], to[cnt] = v, head[u] = cnt;
}
void DP(const int u, const int fa) {
int pos = lower_bound(f + 1, f + n + 1, w[u]) - f;//找到第一个大于等于 w[u] 的数并替换,保证和前面也可构成合法子序列
ans = max(ans, pos);
int tmp = f[pos]; f[pos] = w[u];
for(int i = head[u]; i; i = nxt[i]) if(to[i] != fa) DP(to[i], u);
f[pos] = tmp;//回溯,所以只用赋值一次 inf
}
int main() {
int u, v;
n = read();
for(int i = 1; i <= n; ++ i) w[i] = read();
for(int i = 1; i < n; ++ i) {
u = read(), v = read();
addEdge(u, v), addEdge(v, u);
}
memset(f, 0x3f, sizeof f);//先用 inf 占位
for(int i = 1; i <= n; ++ i) DP(i, 0);
printf("%d\n", ans);
return 0;
}
解法二
咕咕咕~