18. Исполнитель Робот: #297267
Квадрат разлинован на $N\times N$ клеток, где $1<N<30$. Исполнитель Робот может перемещаться по клеткам, выполняя команды вправо и вниз. Между соседними клетками могут находиться внутренние стены, через которые пройти нельзя.
В каждой клетке лежит монета достоинством от $1$ до $100$. Посетив клетку, Робот забирает монету с собой, включая начальную и конечную клетки маршрута.
Определите максимальную и минимальную денежные суммы, которые может собрать Робот, пройдя из левой верхней клетки в правую нижнюю. В ответе укажите сначала максимальную сумму, затем минимальную.
Пример входных данных:

В исходном файле таблица занимает диапазон $A1:T20$, поэтому $N=20$.
Внутренние стены расположены справа от клеток $F4:F15$ и снизу от клеток $L17:Q17$.
Расчётную таблицу разместим справа от исходной, начиная с ячейки $V1$.
В $V1$ запишем: $=A1$
В $W1$: $=V1+B1$ и скопируем вправо до $AO1$.
В $V2$: $=V1+A2$ и скопируем вниз до $V20$.
Для поиска максимальной суммы в $W2$ запишем: $=B2+МАКС(W1;V2)$ и скопируем в диапазон $W2:AO20$.
Для первых клеток:
$V1=101$,
$W1=101+34=135$,
$V2=101+48=149$,
$W2=58+\max(135;149)=207$.
Теперь учтём стены. Из-за стены справа от $F4:F15$ в клетки $G4:G15$ можно попасть только сверху. В расчётной таблице это диапазон $AB4:AB15$.
В $AB4$ запишем: $=G4+AB3$ и скопируем до $AB15$.
Через стену снизу от $L17:Q17$ нельзя пройти вниз, поэтому в клетки $L18:Q18$ можно попасть только слева.
В $AG18$ запишем: $=L18+AF18$ и скопируем вправо до $AL18$.
В ячейке $AO20$ получим максимальную сумму: $2691$.
Для поиска минимальной суммы в обычных клетках вместо МАКС используем МИН: $=B2+МИН(W1;V2)$
Для первых клеток: $W2=58+\min(135;149)=193$.
Формулы около стен остаются такими же: $AB4=G4+AB3$, $AG18=L18+AF18$.
В ячейке $AO20$ получим минимальную сумму: $1795$.
Ответ: $2691$ $1795$.
Код на Python
Если сохранить исходную таблицу в формате CSV с именем 18-28.csv, результат можно проверить программой:
s = tuple(
tuple(map(int, row.split(';')))
for row in open('18-28.csv').read().splitlines()
)
N = len(s)
mn = [[10 ** 9] * N for _ in range(N)]
mx = [[-10 ** 9] * N for _ in range(N)]
mn[0][0] = mx[0][0] = s[0][0]
# В G4:G15 нельзя войти слева
wall_left = {(i, 6) for i in range(3, 15)}
# В L18:Q18 нельзя войти сверху
wall_top = {(17, j) for j in range(11, 17)}
for i in range(N):
for j in range(N):
if i == 0 and j == 0:
continue
a, b = [], []
if j > 0 and (i, j) not in wall_left:
a.append(mn[i][j - 1])
b.append(mx[i][j - 1])
if i > 0 and (i, j) not in wall_top:
a.append(mn[i - 1][j])
b.append(mx[i - 1][j])
mn[i][j] = s[i][j] + min(a)
mx[i][j] = s[i][j] + max(b)
print(mx[-1][-1], mn[-1][-1])
Программа выводит: $2691$ $1795$.