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)