Liebig's Barrels
Problem
题目大意
给m = n × k块木板,每块木板长ai。要求组成n个桶,每个桶k块木板,每个桶容积数值与组成其所有木板中最短的那块木板长度相等,在任意两个桶容积差不超过l的前提下,问所有桶的容积和最大是多少(若要求不可能满足则输出0)。
算法
将木板按长度从小到大排序得{ap[i]}。
若不考虑l则答案即为sum{ap[i × k]}。
注意,n个桶中容积最小的桶必包含长度最短的木板。因此,这n个桶的容积范围D == [ap[0], ap[0] + l]。当且仅当长度范围在D内的木板数量少于n个,要求不可能被满足。
当要求可以满足时,对于从大到小的每个ap[i × k],若ap[i × k]不在D内则将其与长度在D内且尚未被交换过的最大木板交换位置。设该操作后的木板长度序列为{aq[i]}。
答案:
sum{aq[i × k]}
时间复杂度:
O(mlog(m))
空间复杂度:
O(m)
代码
1 def doit(n, k, l, a): 2 m = n * k 3 a.sort() 4 hen = 0 5 tai = m 6 while ((hen < m) and (a[hen] <= a[0] + l)): 7 hen += 1 8 if (hen < n): 9 return 0 10 for i in range(n): 11 tai -= k 12 if (hen > tai): 13 break 14 hen -= 1 15 a[hen], a[tai] = a[tai], a[hen] 16 temp = 0 17 for i in range(n): 18 temp += a[i * k] 19 return temp 20 21 n, k, l = input().split() 22 a = input().split() 23 for i in range(len(a)): 24 a[i] = int(a[i]) 25 print(doit(int(n), int(k), int(l), a))