Блог пользователя VladKov

Автор VladKov, история, 5 лет назад, По-русски

Не могу разобраться с Динамикой по профилю. В интернете материала мало, понимаю по теории с informatics(https://informatics.msk.ru/mod/resource/view.php?id=5113) и neerc.ifmo. Задача паркет о замощении доминошками 2*1, 1*2 поля n*m. На e-maxx нашел следующий код. (http://e-maxx.ru/algo/profile_dynamics) По моим расчетам, асимптотика составляет O(n*m*2^(2n)), так как calc в худшем случае будет вызаваться по 2 раза по всей длине n. Так ли это? В комментариях указано O(n*m*2^n). Работает быстро И не могу понять дп по излом. профилю. Я читал теорию, о увеличении профилей в 2n, за счёт появления места излома — от 1 до n, и дополнительного бита в маске. Тем не менее, нигде код не нашел. На codeforces нашел такой код, и что то мне подсказывает, что это и есть дп по излому. (https://codeforces.net/gym/100124/submission/2804558)

Код взят к задачи о доминошках. Не могу понять, почему профилей (1 << n), а не (2 << n), что тогда j,и почему при подсчёте маски следующего столбца мы добавляем результат в этот же столбец? Всем благодарен

  • Проголосовать: нравится
  • +14
  • Проголосовать: не нравится

»
5 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Автокомментарий: текст был обновлен пользователем VladKov (предыдущая версия, новая версия, сравнить).

»
5 лет назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

То что на e-maxx — не динамика по изломанному профилю. Раздел 3 из pdf-ки прилинкованной это довольно близко к тому что на e-maxx. Можно оценить как $$$O(n \cdot 2^{2 \cdot m})$$$. Однако на самом деле будет быстрее, так как не все профили между собой совместимы (т.е. не из каждого $$$2^m$$$ состояний можно перейти в другие $$$2^m$$$).

По сути у нас $$$O(n \cdot 2^m)$$$ состояний и из каждого $$$O(2^m)$$$ переходов.

Решение https://codeforces.net/gym/100124/submission/2804558, которые в посте упомянуто — динамика по изломанному профилю.

В упомянутой pdf-ке это раздел 8. Кажется, там достаточно нормально описано и визуализировано как это работает. Просто может стоит посидеть с листком и порисовать :)

В динамике по изломанному профилю у нас заполнены первые i столбцов доминошками, которые полностью лежат в первых i столбцах (т.е. возможны какие-то пропуски, если доминошка будет лежать в i и i+1 столбцах). И столбец i+1 заполнен только частично. А именно мы заполнили первые j строк этого столбца.

Соответственно состояние:

  • i — номер последнего столбца который мы полностью заполнили (за вычетом доминошек, которые на половину будут лежать в i+1).

  • j — столбец до которого (исключительно) мы заполнили столбец i+1.

  • Профиль столбца i.

  • Профиль столбца i+1.

Но так как мы столбец i+1 заполнили только частично, соответсвенно нам нужно знать только первые j строк этого профиля. С другой стороны, эти j строк i+1-го столбца "перекрывают" столбец i. Т.е. когда мы будем заполнять другие клетки столбца i+1 или клетки [0..j) столбца i+2, то клетки [0..j) столбца i никак на это влиять уже не будут, поэтому нам не нужно их знать.

В итоге, нам нужно только знать клетки [0..j) столбца i+1 и клетки [j..n) столбца i. Поэтому, собственно, профиль и называется изломанным.

Получается, что состояний $$$O(m \cdot n \cdot 2^n)$$$ и количество переходов $$$O(1)$$$ -- перебрать как поставить доминошку в текущую клетку (i, j) (место излома профиля).

Ну и в итоге, получаем $$$O(m \cdot n \cdot 2^n)$$$.