Skip to content

28389: 跳高

http://cs101.openjudge.cn/practice/28389

体育老师组织学生进行跳高训练,查看其相对于上一次训练中跳高的成绩是否有所进步。为此,他组织同学们按学号排成一列进行测试。本次测验使用的老式测试仪,只能判断同学跳高成绩是否高于某一预设值,且由于测试仪器构造的问题,其横杠只能向上移动。由于老师只关心同学是否取得进步,因此老师只将跳高的横杠放在该同学上次跳高成绩的位置,查看同学是否顺利跃过即可。为了方便进行上次成绩的读取,同学们需按照顺序进行测验,因此对于某个同学,当现有的跳高测试仪高度均高于上次该同学成绩时,体育老师需搬出一个新的测试仪进行测验。已知同学们上次测验的成绩,请问体育老师至少需要使用多少台测试仪进行测验?

由于采用的仪器精确度很高,因此测试数据以毫米为单位,同学们的成绩为正整数,最终测试数据可能很大,但不超过10000,且可能存在某同学上次成绩为0。

输入

输入共两行,第一行为一个数字N,N<=100000,表示同学的数量。第二行为N个数字,表示同学上次测验的成绩(从1号到N号排列)。

输出

一个正整数,表示体育老师最少需要的测试仪数量。

样例输入

5
1 7 3 5 2

样例输出

3

提示

1.50%的数据中,N<=5000.100%的数据中,N<=100000. 2.可通过观察规律将题目转化为学过的问题进行求解。 3.对于10w的数据,朴素算法可能会超时,可以采用二分法进行搜索上的优化。

Dilworth定理,最小的链覆盖数等于最长反链长度。https://oi-wiki.org/math/order-theory/

python
"""
Dilworth定理:
Dilworth定理表明,任何一个有限偏序集的最长反链(即最长下降子序列)的长度,
等于将该偏序集划分为尽量少的链(即上升子序列)的最小数量。
因此,计算序列的最长下降子序列长度,即可得出最少需要多少台测试仪。
"""

from bisect import bisect_left

def min_testers_needed(scores):
    scores.reverse()  # 反转序列以找到最长下降子序列的长度
    lis = []  # 用于存储最长上升子序列

    for score in scores:
        pos = bisect_left(lis, score)
        if pos < len(lis):
            lis[pos] = score
        else:
            lis.append(score)

    return len(lis)


N = int(input())
scores = list(map(int, input().split()))

result = min_testers_needed(scores)
print(result)