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

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

Наблюдение, касающееся динамического программирования, которое все, скорее всего, уже давно сделали.

Вместо того чтобы строить массив вида DP[dim_1][dim_2][dim_3]...[dim_N], часто бывает более удобно и понятно строить явным образом граф вида vector <struct {int state_1, state_2, state_3, ..., state_N;} >.

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

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

Также это позволяет обойтись вообще без написания циклов в явном виде, всё можно сделать при помощи рекурсивной функции обхода графа.

Таким образом можно добиться даже экономии памяти, если создавать новое состояние непосредственно перед тем, как обход графа собирается пойти в него.

Пример, где такой подход позволил избежать громоздких выкладок с многомерным массивом:

http://acm.timus.ru/problem.aspx?space=1&num=1501 http://ideone.com/tm1TcB

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

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

Лично я не понял, каким образом таки Вы ужали многомерность.

Помимо этого очень много задач динамического программирования могут быть оптимизированы разными способами (монотонность точки разреза, CHT), которые прямо зависят от того, в каком порядке производятся вычисления, что иногда можно поменять какие-нибудь циклы местами и какой-нибудь из подходов станет применимым, хотя не был ранее. Рекурсивная дп хороша для описания решения, действительно она нередко короче итеративной (хотя далеко не всегда), и обычно понятнее, но я всё равно буду придерживаться итеративной, из-за быстродействия и потенциальных оптимизаций

  • »
    »
    7 лет назад, # ^ |
    Rev. 5   Проголосовать: нравится +16 Проголосовать: не нравится

    Первоначально в голову приходит состояние dp[i] [j] [difference], где difference равно разности между красными и черными картами. И когда я начинаю думать в терминах такого dp в итеративном варианте, я запутываюсь в рассуждениях, не вижу как делать переходы, хотя тут конечно тоже можно убрать третий параметр и в итеративном варианте. Получается, что тому, кто имеет уже опыт решения графовых задач, может быть очень полезным решать рекурсивно (если цель именно решить, сдать задачу) , потому что в голове уже есть необходимый отлаженный механизм мышления.

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

    В качестве другого примера на ум приходит: http://acm.timus.ru/problem.aspx?space=1&num=1437

    Здесь мой первый порыв -- это написать динамику по трём измерениям dp[x] [y] [z] , равную искомому количеству способов отмерить различные объемы топлива, где x, y, z -- объемы данных канистр.

    Я провёл некоторое время в безуспешных попытках получить формулу для такой динамики.

    Стоило мне начать думать в терминах графа, где вершина содержит текущее количество топливо в каждой канистре, как сразу стало понятно, что достаточно найти количество вершин достижимых из начального состояния, имеющих различную сумму s=x+y+z параметров.

    То есть фактически этот метод просто помог мне преодолеть инертность мозга.

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

      Так там нужно не количество способов, а true/false. Поэтому ты и не придумал формулу. Не ту задачу решал.

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

По сути ведь это получается просто перебор с запоминанием (memoization)? Если да, то это, на самом деле, довольно хороший способ придумывать динамику, имхо.