Лениво связывая узел для 1-мерного динамического программирования

Несколько лет назад я прошел курс алгоритмов, где мы давали следующую задачу (или такую):

Есть зданиеn этажи с лифтом, который может подниматься только на 2 этажа одновременно и на 3 этажа одновременно. Используя динамическое программирование, напишите функцию, которая будет вычислять количество шагов, которое требуется лифту, чтобы добраться от полаi на полj.

Это очевидно легко при использовании подхода с учетом состояния: вы создаете массив длиной n элементов и заполняете его значениями. Вы могли бы даже использовать технически не сохраняющий состояние подход, который включает в себя накопление результата в виде его рекурсивной передачи. Мой вопрос заключается в том, как сделать это без учета состояния, используя ленивую оценку и завязывая узел.

Я думаю, что разработал правильную математическую формулу:

гдеi+2 а такжеi-3 находятся в пределах допустимых значений.

К сожалению, я не могу заставить его прекратить. Если я поставлюi+2 сначала выберите случай, а затем выберите ровный пол, чтобы оценить четные этажи ниже целевого уровня, но это все. Я подозреваю, что он стреляет прямо на самый высокий ровный этаж для всего остального, падает на 3 уровня, затем повторяется, постоянно колебаясь между несколькими верхними этажами.

Таким образом, это, вероятно, исследование бесконечного пространства (или конечного, но с петлями) в глубине в первую очередь. Я не могу придумать, как исследовать пространство в широком смысле, не используя множество структур данных, которые эффективно имитируют подход с учетом состояния.

Хотя эта простая проблема разочаровывающе трудна, я подозреваю, что, увидев решение в 1-м измерении, я мог бы заставить его работать для 2-мерного варианта задачи.

РЕДАКТИРОВАТЬ: Многие ответы пытались решить проблему по-другому. Сама проблема мне не интересна, вопрос об используемом методе. Подход Хаосматтера к созданиюminimal Функция, которая может сравнивать потенциально бесконечные числа, возможно, является шагом в правильном направлении. К сожалению, если я попытаюсь создать список, представляющий здание с 100 этажами, результат вычислится слишком долго, поскольку решения подзадач не используются повторно.

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

levels = go [0..10]
  where
    go [] = []
    go (x:xs) = minimum
      [ if i == 7
          then 0
          else 1 + levels !! i
        | i <- filter (\n -> n >= 0 && n <= 10) [x+2,x-3] ]
      : go xs

Вы можете увидеть, как1 + levels !! i пытается ссылаться на ранее рассчитанный результат и какfilter (\n -> n >= 0 && n <= 10) [x+2,x-3] пытается ограничить значенияi к действительным. Как я уже сказал, это на самом деле не работает, это просто демонстрируетметод с помощью которого я хочу, чтобы эта проблема была решена. Другие способы решения этой проблемыне мне интересно.

Ответы на вопрос(4)

Ваш ответ на вопрос