思路和高赞的思路一样,但它的答案超时了,所以必须要用bisect模块。

bisect.bisect_left(list,num)

list必须是一个有序序列

num是要查找的元素

返回值是要查找的元素在list中的位置,如果list中没有该元素,那么返回的是该元素应该在的位置

bisect.bisect_left([1,2,3,5],4)返回的就是3

bisect.bisect_left([1,2,3,5],5)返回的也是3

其他的都在代码中注释了,中文没有定语从句长句子太难讲清楚了。。。

import bisect

def max_left_num(lst):#在该同学左边可以最多站多少人,所以算得是留在合唱队里的情况
    list_num = []
    list_max_left_num = []
    for i in lst:
        num_of_left = bisect.bisect_left(list_num,i)
        if num_of_left == len(list_num):
            list_num.append(i)
            list_max_left_num.append(num_of_left)
            """
            这个list_num列表中,位置(num_of_left)表示了在队列左边比该名同学矮的人数
            因为Ti一定要大于Ti-1,且Ti-1一定要大于Ti-2,以此类推
            所以
                如果Ti-n和Ti-n-1左边可以站的人数相同(即num_of_left相同)
                那么只考虑靠Ti最近的那一个的情况即可,即只考虑Ti-n
                这就是为什么else里为什么要将num_of_left相对应的位置替换成最新的数(因为最新的数最靠近下一次遍历的数)。
                if语句条件下考虑的是如果当前数比前面最大的数(本身的值最大and左边比这个数小的数的个数最大)要大
                那么说明这个数同样也比这个最大的数前面那些比这个最大的数小的数大
                所以这个数就在原来那个最大的数的基础上+1就好了,也就是它在列表中的位置+1
            """
        else:
            list_num[num_of_left] = i
            list_max_left_num.append(num_of_left)
    return list_max_left_num

while 1:
    try:
        n = int(input())
        line_from_left_to_right = list(map(int,input().split(" ")))
        line_from_right_to_left = line_from_left_to_right[::-1]
        num_of_left_plus_right = []
        list_left = max_left_num(line_from_left_to_right)
        list_right = max_left_num(line_from_right_to_left)[::-1]
        for i in range(n):
            num_of_left_plus_right.append(list_left[i]+list_right[i]+1)#
        print(n-sorted(num_of_left_plus_right)[-1])
    except:
        break