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

Автор RedLord, 11 лет назад, По-русски

Здравствуйте! Я нашел две задачи, в которых надо вычислять значение функции для достаточно больших графов. Проблема в том, даже битовое сжатие не позволяет хранить их в явном виде.

Первая: http://acm.petrsu.ru/site/problems/problemset/0289/ . Дана некоторая клавиатура (размера 3 на 10) и текст, который робот должен на ней набрать. Нажатие каждого символа занимает одну минуту. Перемещение пальца – одну минуту. Пробел всегда можно набрать одним нажатием (без перемещений).

Палец представляет собой точку (x;y) Никакие 2 пальца не могут находиться в одном столбце клавиатуры. Пальцы также не могут менять порядок (Указательный не становится правее среднего и т.д.). Руки не могут менять порядок, и на одной руке – 4 пальца.

Операция перемещения – изменение координаты x или y пальца, но не обеих сразу.

Так как палец может иметь y от 1 до 3, и быть сдвинутым не более чем на 2 позиции (иначе какие-то из них будут меняться местами), для кодирования достаточно 9 значений. Всего 9^8=43046721.

Всего символов 20, и даже если мы научимся вычислять расстояние между позициями за без дополнительной памяти, граф [позиция][номер символа] будет иметь 344373768 вершин при ML 256Мб. (TL=5 с)

Жадность не проходит, например если к клавиатуре из условия набрать текст pon (указательный палец переместится на p, и далее не будет разницы, каким из двух ближайших пальцев набирать o, хотя указательным правой — выгоднее)

Брутфорс по пальцам, которыми мы набираем текущий символ, не проходит по времени, если символы на клавиатуре повторяются.

Вторая лежит в архиве комбинаторных алгоритмов того же сайта под номером 24. Это единственная задача, которую я видел, с ограничением по времени в 180 секунд. (ML – 256Mb).

В ней надо найти количество кратчайших путей коня по доске n x n из левого верхнего угла в правый нижний. n до 10^5

Проблема с конем в том, что для обхода графа без циклов обычно используется массив пометок, который для каждой вершины хранит, была ли она обработана, либо граф обходится в порядке топологической сортировки. Оба этих подхода здесь дают ML.

Вообще, для расчета значения в клетке нужен только квадрат 5 на 5 клеток с центром в ней. Но верхняя клетка может рассчитываться через нижнюю, а нижняя через верхнюю (тоже верно для левой/правой), поэтому нельзя просто рассматривать ряды таких квадратов, отсекая их от доски.

Буду благодарен за помощь.

Upd: Архив комбинаторных алгоритмов:http://acm.petrsu.ru/site/contest/combalgs_archive Ссылка на pdf второй задачи: acm.petrsu.ru/site/problems/combalgs_archive/024/

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

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

В первой задаче вы слишком грубо оценили количество состояний. Вот точная оценка: у нас каждый палец может независимо находиться в любом y. Значит, уже есть 38. А вот с x интереснее: так как в каждом столбце находится не более одного пальца и порядок фиксирован, то по набору из 8 столбцов однозначно определяется кто где находится. Сочетаний из 10 по 8 всего штук. Итого 38·45 = 295 245 состояний. Домножаем на 20 символов в строке, получаем 6 миллионов состояний, что довольно немного.

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

Вторая задача совсем простая, решается обычным поиском в ширину. Достаточно заметить, что нам нужно хранить не все состояния, а только несколько диагоналей. Проэмулируйте визуально алгоритм у себя в голове, все станет понятно.

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

    Какие именно диагонали надо хранить? Диагональ можно удалить из памяти, если конь обошел все ее элементы. Уже для n=175 встречаются диагонали, которые содержат клетки, с расстояниями от начальной в диапазоне [59;87], т.е. они хранятся достаточно долго. Их можно выкидывать их по какому-то другому критерию?

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

Мне вот интересно, я сам должен искать на сайте вторую задачу? Я минут пять искал, спасибо, свой минус ты заслужил. Так сложно ссылку дать?

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

    Вообще, я не знал, что на архив комбинаторных алгоритмов можно дать ссылку. (Там много контестов, которые доступны только через систему) http://acm.petrsu.ru/site/contest/combalgs_archive 24-я Ссылка на pdf acm.petrsu.ru/site/problems/combalgs_archive/024/

    • »
      »
      »
      11 лет назад, # ^ |
      Rev. 4   Проголосовать: нравится -8 Проголосовать: не нравится

      Для решения задачи нужно применить формулу, получив при этом достаточно большое значение в длинной арифметике. Формулу можно найти на oeis по нескольким первым ответам. Возможно можно её как-то вывести самому, но лень думать.

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

        TL в 180 секунд говорит о существовании более понятного решения.

        • »
          »
          »
          »
          »
          11 лет назад, # ^ |
          Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

          Не думаю. Просто ответ порядка 100 000 двоичных знаков. Если бы требовалось найти решение по модулю, то можно реализовать "тупой" алгоритм за N^2 / 6, просто матрицу следует заполнять с одной стороны от главной диагонали, и следить за тем чтобы мы не выходили за область клеток находящихся на кратчайших путях. Не удивлюсь если можно улучшить до N^2 / 12, заполняя матрицу не далее чем до побочной диагонали. В любом случае 180 секунд не хватит чтобы найти ответ из 100 000 двоичных знаков.