Это эквивалентно проблеме разбиения , где каждый элемент во входном мультимножестве является длиной объединения.Кроме того, эту проблему всегда можно решить с помощью простой жадной реализации, которая выполняется за время O (n).Например, рассмотрим следующий ввод:
Union 1: a a a
Union 2: b b b b b b b b b
Union 3: c c c c c c c c c c
Union 4: d d d d d d d d d d
Union 5: e e
Простой жадный алгоритм создает два списка вывода.Для каждого объединения (начиная с объединения, которое имеет наибольшее количество элементов), элементы объединения добавляются в более короткий список вывода.В результате получается два списка, например:
c c c c c c c c c c b b b b b b b b b
d d d d d d d d d d a a a e e
Следующий шаг - взять некоторые элементы из конца более длинного списка и добавить их в начало более короткого списка.В этом примере два b
s перемещены:
c c c c c c c c c c b b b b b b b
b b d d d d d d d d d d a a a e e
Так будет ли это работать всегда?Да, единственное исключение - когда один союз содержит более половины от общего количества предметов.В этом случае элементы не перемещаются из более длинного списка.
Вот пример реализации на python:
inputList = [['a','a','a'],
['b','b','b','b','b','b','b','b','b'],
['c','c','c','c','c','c','c','c','c','c'],
['d','d','d','d','d','d','d','d','d','d'],
['e','e']]
topCount = 0
botCount = 0
topList = []
botList = []
# sort the input in descending order based on length
inputList = sorted(inputList, key=lambda x:len(x), reverse=True)
# greedy partitioning into two output lists
for itemList in inputList:
if topCount <= botCount:
topList += itemList
topCount += len(itemList)
else:
botList += itemList
botCount += len(itemList)
# move some elements from the end of the longer list to the beginning of the shorter list
if topList[0] != topList[-1]:
if topCount > botCount+1:
excess = (topCount - botCount) // 2
botList = topList[-excess:] + botList
topList = topList[:-excess]
elif botCount > topCount+1:
excess = (botCount - topCount) // 2
topList = botList[-excess:] + topList
botList = botList[:-excess]
print topList
print botList
Вывод:
['c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'b', 'b', 'b', 'b', 'b', 'b', 'b']
['b', 'b', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'a', 'a', 'a', 'e', 'e']