[华为练习题]——合唱队
题目描述
计算最少出列多少位同学,使得剩下的同学排成合唱队形
说明:N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1<T2<…<Ti-1Ti+1>…>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,希望能有所收获!