zoukankan      html  css  js  c++  java
  • 牛客练习赛39 B.选点

    链接:https://ac.nowcoder.com/acm/contest/368/B
    来源:牛客网
     

    题目描述

    有一棵n个节点的二叉树,1为根节点,每个节点有一个值wi。现在要选出尽量多的点。

    对于任意一棵子树,都要满足:

    如果选了根节点的话,在这棵子树内选的其他的点都要比根节点的值

    如果在左子树选了一个点,在右子树中选的其他点要比它

    输入描述:

    
     

    第一行一个整数n。

    第二行n个整数wi,表示每个点的权值。

    接下来n行,每行两个整数a,b。第i+2行表示第i个节点的左右儿子节点。没有为0。

    n,a,b≤10^5,   −2×10^9≤wi≤2×10^9 

    输出描述:

    一行一个整数表示答案。

    示例1

    输入

    复制

    5
    1 5 4 2 3
    3 2
    4 5
    0 0
    0 0
    0 0 

    输出

    复制

    3

    思路:问题转换为求二叉树的前序遍历序列(先右后左)的一个最长上升子序列的长度。。。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    int n;ll w[100005];
    int l[100005];int r[100005];
    int ans=0;
    ll b[100005];int cnt=0;
    void dfs(int i)
    {
        b[cnt++]=w[i];
        if(r[i]!=0)dfs(r[i]);
        if(l[i]!=0)dfs(l[i]);
    }
    int tmp[100005];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%lld",&w[i]);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&l[i],&r[i]);
        }
        dfs(1);
        int len=0;
        for(int i=0;i<cnt;i++)
        {
            int id=lower_bound(tmp,tmp+len,b[i])-tmp;
            tmp[id]=b[i];
            len=max(len,id+1);
        }
        cout<<len<<endl;
        return 0;
    }
    
  • 相关阅读:
    [Linux]-配置多台机器的SSH相互信任
    [Linux]-常用代码块
    [Linux]-Shell编程与规范
    [Sqoop]-任务
    [Sqoop]-导入导出
    [Sqoop]-认识&部署
    [Hive]-函数篇
    Tomcat catalina.out日志使用log4j按天分割
    技术站点
    Linux监控命令
  • 原文地址:https://www.cnblogs.com/linruier/p/10358673.html
Copyright © 2011-2022 走看看