Школа программиста

Забыли пароль?
[задачи] [курсы] [олимпиады] [регистрация]
Логин:   Пароль:    
Скрыть меню
О школе
Правила
Олимпиады
Фотоальбом
Гостевая
Форум
Архив олимпиад
Архив задач
Состояние системы
Рейтинг
Курсы
Новичкам
Работа в системе
Курсы ККДП
Дистрибутивы
Статьи
Ссылки


 

Количество путей в лабиринте

(Время: 1 сек. Память: 16 Мб Сложность: 38%)

Для решения данной задачи применим принцип динамического программирования. Предположим, что для каждой клетки с некоторыми координатами (i,j) нам уже известно количество путей длиной в m шагов. Обозначим это значение как a[m][i][j]. Тогда завершающий шаг любого пути длиной m+1 в клетку (i,j) обязательно будет следовать из соседних клеток (i,j-1), (i,j+1), (i-1,j) и (i+1,j). Поэтому верно рекуррентное соотношение:

a[m+1][i][j]=a[m][i][j-1]+a[m][i][j+1]+a[m][i-1][j]+a[i+1][j]

Заметим, что все значения a[0][i][j] нам известны (они равны нулю, кроме a[0][1][1]=1), поэтому увеличивая m мы сможем вычислить количество путей для k шагов для каждой клетки. Ответом на задачу будет значение a[k][n][n]. Данный алгоритм можно представить следующим образом:

  int a[31][16][16]
  string c[1..15]

  readln(n, k)
  for i=1..n readln(c[i])

  a[0][1][1]=1
  for m=1..k
    for i=1..n
      for j=1..n
        if(c[i][j]='0') 
          a[m][i][j]=a[m-1][i][j-1]+a[m-1][i-1][j]+a[m-1][i][j+1]+a[m-1][i+1][j]

  write(a[k][n][n])

Заметим, что на каждом шаге нам достаточно знать значения, вычисленные на предыдущем, поэтому в целях экономии памяти можно ограничиться массивом меньшей размерности (использовать только 2 значения первой координаты).

[Обсуждение] [Все попытки] [Задача]


Красноярский краевой Дворец пионеров, (c)2006 - 2026, ИНН 246305493507, E-mail: admin@acmp.ru