Существует отсортированный мульти-набор из N целых чисел, где N <26, например: [1x4,2,5x2,6x2,15,55] И некоторая сумма - например, 10. Я хотел бы получить максимальное число множество множеств сверху, которые, по крайней мере, равны данной сумме. Например: </p>
- [1x3 + 2 + 5] = 10 - первый вспомогательный мульти-набор
- [5 + 6] = 11 - второй мульти-набор
- [ 15] - третий набор
- [55] - четвертый набор
1,6 - остатки. (но, как видите, это не единственный ответ). Как лучше всего подойти к этой проблеме? Я пытаюсь решить эту проблему в java, но приветствуется любое решение с объяснением.
Редактировать: В настоящее время я пытаюсь использовать следующий подход:
- Создание нескольких наборов из одного элемента которые выше или равны сумме. Удалить их из оригинального набора.
- Найти 2 подмножества элементов, которые в точности равны сумме. Удалите их из оригинального набора <- я на этом этапе </li>
И теперь я не знаю, как продвигаться или мой подход правильный.
Вопрос в том, в какой момент я должен начать принимать подмножественные множества, превышающие сумму, и как проверить, не приведет ли это к потере некоторых множеств, которые можно было бы создать иначе?
Пока у меня есть что-то вроде этого:
private static String findAndRemoveMultisetsEqualTo(SortedMultiset<Integer> numbers, int searchForSum) {
String answer = "";
if (numbers.lastEntry().getElement() >= searchForSum) {
answer += "\nSet of " + searchForSum + " [" + numbers.lastEntry().getElement() + "]";
numbers.remove(numbers.lastEntry().getElement());
answer += " => " + String.valueOf(numbers);
return answer;
} else {
answer += findAndRemoveExactPairSumInMultiSet(numbers, searchForSum);
}
return answer;
}
private static String findAndRemoveExactPairSumInMultiSet(SortedMultiset<Integer> numbers, final int searchForSum) {
String answer = "";
List<Integer> tempList = numbers.stream().filter(number -> number <= (searchForSum / 2)).collect(Collectors.toList());
for (Integer number : tempList) {
if (numbers.contains(searchForSum - number) && (!number.equals(searchForSum - number))) {
answer += "\nSet of " + searchForSum + " [" + number + "," + (searchForSum-number) + "]";
numbers.remove(number);
numbers.remove(searchForSum - number);
answer += " => " + String.valueOf(numbers);
} else if (number.equals(searchForSum - number) && numbers.contains(number) && numbers.count(number) > 1) {
answer += "\nSet of " + searchForSum + " [" + number + "," + number + "]";
numbers.remove(number, 2);
answer += " => " + String.valueOf(numbers);
}
}
return answer;
}