Динамическое программирование. Спичечная модель
Здравствуйте, Хабрахабр. В этом после я хочу рассказать о динамическом программировании на примере решения одной из задач. С этой задачей я недавно столкнулся на портале олимпиадных задач (ссылка указана в конце). Сразу перейду к делу.
Профессор Самоделкин решил изготовить объемную модель кубиков из спичек, используя спички для рёбер кубиков. Длина ребра каждого кубика равна одной спичке.
Для построения модели трех кубиков он использовал 28 спичек.
Какое наименьшее количество спичек нужно Самоделкину для построения модели из N кубиков?
Все числа в задаче не превышают 2·10 9 .
Входные данные
Одно число N – количество кубиков.
Выходные данные
Одно число – количество спичек.
Я решил эту задачу используя динамическое программирование, но ее можно было решить и другими способа, и даже просто одной формулой — которую мы выведем в конце.
Поделки из спичек своими руками с помощью клея
Решение
- Решить задачу для 1D случая и в нем буду использовать квадрат со стороной в 1 спичку, вывести формулу
- Решить задачу для 2D случая и в нем буду использовать квадрат со строной в 1 спичку, вывести формулу
- Найти закономерности в 1D и 2D случае и на их основе решить задачу для 3D случая, вывести формулу для 3D случая
- Мысли на счет n-мерного случая
И так установим условия задачи:
Нам нужно узнать минимального количество спичек которое необходимо что бы построить линию из N квадратов со стороной в 1 спичку
Для хранения результата я буду использовать массив DP.
Теперь смотрим на рисунок и заполняем этот массив числами которые нужно прибавить к решению для i-1 случая:
N: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
DP: | 0 | 4 | 3 | 3 | 3 | 3 | 3 | 3 |
И ответом для N будет сумма элементов массива DP от 0 до N, и сразу видим закономерность — для DP[1]:=4, DP[>1]:=3
и выводим формулу(N всегда > 1, т.е. натуральное):
Result(N):= SUM(DP1->DPN) = 4+(N-1)*3
Задача:
Нам нужно узнать минимального количество спичек которое необходимо для построения квадратов со стороной в 1 спичку. Строить можно в 2 измерениях.
В 2D у нас появляется новая проблема: к плоскости какого размера A х B нужно стремится что бы минимизировать количество спичек? И как многие догадались, это конечно же квадрат. Но не все так просто, там нужно упростить эту идею.
Внимательно посмотрим и видим закономерность: мы имеем плоскость A x B чтобы минимизировать количество ребер, следующие для построения плоскости будут (A+1) x B и потом (A+1) x (B + 1), последняя является квадратом, так как мы начинаем строить из 1 х 1
Result:= 4
newN:= 1
A:= 2
B:= 1
while newN begin
Result:= Result + 1D(min(A,B)) // 1D(N):=3+(N-1)*2 если N >= 1, иначе 0
(A <b)?A++:B++
newN=A*B
end
(A>B)?A—:B—
Result:= Result+ 1D(N-A*B)
И формула:
Result(N):=4+3*(количество полных квадратов которые есть до числа N без 1 + дополнительные числа которые идут перед полными квадратами)+2*(все остальное)
NSQRT:= int(sqrt(N))-1
NADD:= NSQRT + 1(если N SQRT*(NSQRT+1))
Result(N):=4+3*(NSQRT+NADD)+2*(N-NSQRT-NADD)
Вот добрались и до 3Д случая
В трехмерном случае, для минимализации количества спичек для построения, теперь уже, кубов нужно стремится к построению большого куба, но в промежуточных вариантах это будет:
A x B x C -> (A+1) x B x C -> (A+1) x (B+1) x C -> (A+1) x (B+1) x (C+1)
Как получить квадрат, убрав спички
Попробуйте сделать квадрат из спичек, положив на каждую сторону четырехугольника по две составляющие. Внутри выложите крест из четырех палочек — он разобьет фигуру на равные части. Всего вам потребуется двенадцать спичек. Перед вами – заготовка для многих головоломок.
Уберите из исходной фигуры-решетки верхнюю спичку, составляющую крест. Затем — перпендикулярную ей палочку. Получился один большой квадрат, в левом правом углу которого разместился второй, маленький. Ваши манипуляции станут ответом на загадку: «Как убрать две спички (не притрагиваясь к остальным), чтобы из пяти (одного внешнего и четырех внутренних) квадратов получилось два?».
Подумайте, как еще можно преобразовать исходную фигуру, убирая или переставляя определенное количество ее элементов. Попробуйте по-разному выстраивать четырехугольники – так вы можете сами придумать интересную головоломку.
К примеру, условие задачи из пункта №2 можно постоянно менять: a) «Как переставить три спички, чтобы из пяти квадратов получилось три»; b) «Как переложить четыре спички, чтобы из пяти квадратов вышло два» и т.д.
Головоломки со спичками интересны тем, что каждая из них с первого взгляда кажется сложной. Однако решение очень простое. Так, попробуйте выполнить условие задачи из пункта №4, подпункта a).
Достаточно убрать пару спичек, составляющую верхний левый прямой угол исходной фигуры; палочку из ее нижней правой части. Из трех убранных спичек к одной из нижних сторон исходной фигуры пристраивается новый квадрат. Вышло три маленьких четырехугольника, расставленных в шахматном порядке.
Решите остальные головоломки. Для выполнения условия подпункта b) возьмите спички, составляющие крест внутри большого квадрата, и выстроите из них маленький четырехугольник внутри исходной фигуры или рядом с ней.
Сделайте решетку из девяти квадратов (в нее войдет уже двадцать четыре спички). Попробуйте убрать восемь спичек, чтобы получить внутренний квадрат во внешнем. Или снимите четыре спички с середины каждой стороны исходной решетки – получится «шахматная доска», пять маленьких четырехугольников.
Сложите из шестнадцати спичек четыре квадрата. Как получить из них пять таких же фигур, расставив спички иначе? Просто соедините квадраты углами, чтобы между ними получился еще один, внутренний, четырехугольник.
Постройте зигзаг из двадцати четырех палочек: четыре спички горизонтально; переход вниз из одной спички; еще четыре горизонтально выложенные палочки и т.д.). Теперь попробуйте выстроить из этой ломаной линии внешний квадрат (шестнадцать составляющих) и внутренний (восемь палочек).
Продолжайте постепенно усложнять действия задач со спичками, выстраивая более сложные фигуры с большим количеством составляющих. Увлекательность головоломок зависит от вашего воображения и умения логически мылить.
Как сделать Кубик из спичек
Как сделать домик со спичек
Contents