Codeforces 490F Treeland Tour 树形dp

Treeland Tour

离散化之后, 每个节点维护上升链和下降链, 感觉复杂度有点高, 为啥跑这么快。。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long

using namespace std;

const int N = 6000 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

int n, tot, ans, r[N], hs[N];
short up[N][N], dn[N][N];
vector<int> G[N];

void dfs(int u, int fa) {
    for(int i = r[u]; i <= tot; i++) up[u][i] = 1;
    for(int i = 1; i <= r[u]; i++) dn[u][i] = 1;
    for(auto& v : G[u]) {
        if(v == fa) continue;
        dfs(v, u);
        int mx1 = 0, mx2 = 0;
        for(int i = 1; i <= tot; i++) {
            if(up[v][i] + dn[u][i + 1] > ans) ans = up[v][i] + dn[u][i + 1];
            if(dn[v][i] + up[u][i - 1] > ans) ans = dn[v][i] + up[u][i - 1];
        }
        for(int i = 1; i <= tot; i++) {
            if(up[v][i] > up[u][i]) up[u][i] = up[v][i];
            if(dn[v][i] > dn[u][i]) dn[u][i] = dn[v][i];
            if(i < r[u] && up[v][i] > mx1) mx1 = up[v][i];
            if(i > r[u] && dn[v][i] > mx2) mx2 = dn[v][i];
        }
        if(mx1 + 1 > up[u][r[u]]) up[u][r[u]] = mx1 + 1;
        if(mx2 + 1 > dn[u][r[u]]) dn[u][r[u]] = mx2 + 1;
        for(int i = 1; i <= tot; i++) up[u][i] = max(up[u][i], up[u][i - 1]);
        for(int i = tot; i >= 1; i--) dn[u][i] = max(dn[u][i], dn[u][i + 1]);
    }
    if(up[u][tot] > ans) ans = up[u][tot];
    if(dn[u][1] > ans) ans = dn[u][1];
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &r[i]);
        hs[++tot] = r[i];
    }
    sort(hs + 1, hs + tot + 1);
    tot = unique(hs + 1, hs + tot + 1) - hs - 1;
    for(int i = 1; i <= n; i++)
        r[i] = lower_bound(hs, hs + tot, r[i]) - hs;
    for(int i = 2; i <= n; i++) {
        int u, v; scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1, 0);
    printf("%d
", max(1, ans));
    return 0;
}

/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/10466028.html