题目:选点
分析:
看似是树形dp,其实是个LIS
考虑到父节点跟左右儿子的大小关系,将三者按根、右儿子、左儿子排成一个数组,然后跑LIS即可,太妙了,我又没想出来。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;//三年竞赛一场空,不开long long见祖宗
//typedef __int128 lll;
#define print(i) cout << "debug: " << i << endl
#define close() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define mem(a, b) memset(a, b, sizeof(a))
#define pb(a) push_back(a)
#define x first
#define y second
typedef pair<int, int> par;
const ll mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int inf = 0x3f3f3f3f;
int n;
int l[maxn], r[maxn];
ll v[maxn], w[maxn];
int dp[maxn];
int len, tot;
void dfs(int u)
{
if(!u) return;
w[++tot] = v[u];
dfs(r[u]), dfs(l[u]);
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++) cin >> v[i];
for(int i = 1; i <= n; i++)
cin >> l[i] >> r[i];
dfs(1);
for(int i = 1; i <= n; i++)
{
int id = upper_bound(dp + 1, dp + len + 1, w[i]) - dp;
if(id == len + 1) dp[++len] = w[i];
else dp[id] = w[i];
}
cout << len << endl;
}