Minimal Height Tree(思维、贪心)

Minimal Height Tree

题意

给定一个元素个数为 n n n的序列 a a a,这个序列是一棵树宽度优先遍历得来的。这棵树有几个特点:根的编号为 1 1 1、任意节点的孩子结点的编号依次递增、任意两个节点的编号不相同。现在要求所有满足要求的树的最小高度。

数据范围

1 ≤ T ≤ 1000 1 \leq T \leq 1000 1T1000
2 ≤ n ≤ 2 ∗ 1 0 5 2 \leq n \leq 2*10^5 2n2105
1 ≤ a i ≤ n ; a i ≠ a j ; a 1 = 1 1\leq a_i\leq n; a_i≠a_j; a_1=1 1ain;ai=aj;a1=1
∑ n ≤ 2 ∗ 1 0 5 \sum n \leq 2*10^5 n2105

思路

这里的贪心性质很容易发现,就是如果当前遍历到的数可以放在这一层的话,那它就不会放在下一层,这一点证明非常容易。
根据这个性质,我们就可以很容易的将树建立出来。存放一下上一层的空闲节点(指还没有孩子节点的节点),同时存放当前层已经有多少节点了,然后维护上一个数以及答案。这题就可以在 O ( n ) O(n) O(n)的时间复杂度下做完了。

代码

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
    	int n, ans = 0;
        scanf("%d",&n);
        int root;
        scanf("%d",&root);
        int last = root;
        int num = 0, tmp = 0;
        for(int i=2;i<=n;i++){
            int x;
            scanf("%d",&x);
            if(last>x){
                if(num==0) ans ++, num = tmp - 1, tmp = 1;
                else num --, tmp ++;
            }
            else tmp ++;
            last = x;
        }
        printf("%d\n",ans+1);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值