题意:规则:如果选了根节点的话,在这棵子树内选的其他的点都要比根节点的值大;如果在左子树选了一个点,在右子树中选的其他点要比它小。按照以上规则,求在题目所给的二叉树中能选出最多的点的数量。
思路:对于一颗树选出得点的权值的关系为:根节点 右子树 左子树。所以我们可以按照根节点、右子树、左子树进行 遍历,然后按照这个 序求 即为答案。
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
int n;
int w[100005];
int e[100005][2], dp[100005], len;
void dfs(int vertex)
{
dp[++len] = w[vertex];
if(e[vertex][1])
dfs(e[vertex][1]);
if(e[vertex][0])
dfs(e[vertex][0]);
}
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%d", &w[i]);
for (int i = 1; i <= n; ++i)
scanf("%d%d", &e[i][0], &e[i][1]);
len = 0;
dfs(1);
dp[len = 0] = -2000000001;
for (int i = 1; i <= n; ++i)
if (dp[len] < dp[i])
dp[++len] = dp[i];
else
dp[lower_bound(dp + 1, dp + 1 + len, dp[i]) - dp] = dp[i];//非降换为>=以及upper_bound
printf("%d\n", len);
return 0;
}