牛客练习赛39 - B 选点 dfs+lis

题目链接

题意:规则:如果选了根节点的话,在这棵子树内选的其他的点都要比根节点的值大;如果在左子树选了一个点,在右子树中选的其他点要比它小。按照以上规则,求在题目所给的二叉树中能选出最多的点的数量。

思路:对于一颗树选出得点的权值的关系为:根节点 < < 右子树 < < 左子树。所以我们可以按照根节点、右子树、左子树进行 d f s dfs 遍历,然后按照这个 d f s dfs 序求 l i s lis 即为答案。

#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;
}

猜你喜欢

转载自blog.csdn.net/a302549450/article/details/86815664