[华为练习题]——合唱队

[华为练习题]——合唱队

题目描述

计算最少出列多少位同学,使得剩下的同学排成合唱队形
说明:N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1…>TK。 你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。


解题思路

这其实是一道求解最长上升子序列的问题,所谓的合唱队形就是一个最长上升子序列的拼接,只要求出从队列首(左边)到位置i的最长上升子序列,以及从队列尾到位置i的最长上升子序列,将两个子序列的长度相加即为合唱队的总长度,另外我们还知道总的人数,减一下就知道需要出列多少人了。

import bisect
def Solution(mylist):
    dp = [9999] * len(mylist)
    dp[0] = mylist[0]
    num = []
    num.append(1)
    for i in range(1, len(mylist)):
        pos = bisect.bisect_left(dp, mylist[i])
        dp[pos] = mylist[i]
        num.append(pos+1)
    return num

while True:
    try:
        N = int(input())
        mylist = list(map(int, input().split()))
        left = Solution(mylist)
        right = Solution(mylist[::-1])
        right = right[::-1]
        result = 0
        for i in range(N):
            if left[i] + right[i] - 1 > result:
                result = left[i] + right[i] - 1
        print(N - result)
    except:
        break

当然这里我只写了最长上升子序列的一种求解方法,其他的方法可以参看我的另一篇blog[Leetcode]——Longest increasing subsequence,希望能有所收获!

你可能感兴趣的:(笔试编程)