Имеется следующая задача:
В спортивном зале города N появилась штанга и набор блинов с различными массами. Для занятия спортом необходимо распределить блины по двум концам штанги таким образом, чтобы суммарный вес по оба конца штанги был одинаковый. Рассчитайте максимальный вес, который смогут поднимать спортсмены при заданном наборе блинов (с допущением, что гриф штанги невесомый).
Решение должно быть представлено в виде java-программы, у которой:
На входе: массив целых чисел, обозначающих веса блинов, входящих в набор. На выходе: целое число, обозначающее максимальный вес, который можно поднять с заданным набором блинов.
Примеры:
[1,2,3,6]12{1,2,3} с одной стороны и блин {6} с другой, что в сумме даст 12.[1,2,3,4,5,6]20{2,3,5} с одной стороны и блины {4,6} с другой, что в сумме даст 20. Оставшийся блин {1} не может быть нацеплен ни с одной из сторон без потери равновесия.[1,2]0Ограничения:
0 до 20 фунтов.1 до 1000 блинов.10000 фунтов.Сейчас учусь java и решаю задачи. Никак не могу найти подход к данной задачи. Помогите пожалуйста решить, или направьте мысль в нужное русло.
Например так
List<Integer> weights = Arrays.asList(1, 2, 3, 6);
int size = weights.stream()
.mapToInt(x -> x)
.sum() / 2 + 1;
int[] arr = new int[size];
arr[0] = 2;
for (int weight : weights) {
for (int i = size - 1; i >= 0; i--) {
if (arr[i] > 0 && i + weight < size) {
arr[i + weight]++;
}
}
}
for (int i = size - 1; i > 0; i--) {
if (arr[i] >= 2) {
System.out.println(i);
break;
}
}
EDIT
Я все таки домучал. Решение получилось почти в лоб. Оно строит все возможные способы получить все возможные суммы. Затем находит наибольшую сумму у которой есть два не пересекающихся разложения.
public class App {
public static void main(String[] args) {
List<W> weights = Stream.of(1, 2, 3, 4, 5, 9)
.map(W::new)
.collect(Collectors.toList());
Map<Integer, List<List<W>>> arr = new HashMap<>();
arr.put(0, Collections.singletonList(Collections.emptyList()));
for (W weight : weights) {
arr = arr.entrySet().stream()
.flatMap(x -> {
int newWeight = x.getKey() + weight.value;
List<List<W>> newList = x.getValue().stream()
.map(ArrayList::new)
.peek(y -> y.add(weight))
.collect(Collectors.toList());
return Stream.of(
new Pair<>(newWeight, newList),
new Pair<>(x.getKey(), x.getValue())
);
}
)
.collect(Collectors.toMap(
Pair::getIndex,
Pair::getValue,
(x, y) -> {
List<List<W>> r = new ArrayList<>(x);
r.addAll(y);
return r;
}));
}
arr.entrySet().
stream()
.sorted(Comparator.comparing(Map.Entry::getKey, Comparator.reverseOrder()))
.filter(x ->
{
for (List<W> a : x.getValue()) {
for (List<W> b : x.getValue()) {
if(a == b) continue;
if (a.stream().noneMatch(b::contains)) {
return true;
}
}
}
return false;
})
.map(Map.Entry::getKey)
.findFirst()
.ifPresent(System.out::println);
}
@Data
static class Pair<T> {
private final int index;
public final T value;
}
@AllArgsConstructor
@Getter
static class W {
public final int value;
}
}
Класс W нужен чтобы различать блины с одинаковыми весами.
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости