PythonВывести маршрут максимальной стоимости В левом верхнем углу прямоугольной таблицы размером N×M находится черепашка. В каждой клетке таблицы записано некоторое число. Черепашка может перемещаться вправо или вниз, при этом маршрут черепашки заканчивается в правом нижнем углу таблицы. Подсчитаем сумму чисел, записанных в клетках, через которую проползла черепашка (включая начальную и конечную клетку). Найдите наибольшее возможное значение этой суммы и маршрут, на котором достигается эта сумма. Входные данные В первой строке входных данных записаны два натуральных числа N и M, не превосходящих 100 — размеры таблицы. Далее идут N строк, каждая из которых содержит M чисел, разделенных пробелами — описание таблицы. Все числа в клетках таблицы целые и могут принимать значения от 0 до 100. Выходные данные Первая строка выходных данных содержит максимальную возможную сумму, вторая — маршрут, на котором достигается эта сумма. Маршрут выводится в виде последовательности, которая должна содержать N−1 букву D, означающую передвижение вниз и M−1 букву R, означающую передвижение направо. Если таких последовательностей неКак узнать сколько, необходимо вывести ровно одну (любую) из них.
Эта задача сводится к задаче поиска пути на графе пространства состояний.
Состояние - положение черепашки на поле - (x, y).
Граф пространства состояний состоит из таких вершин-состояний, их количество N * M.
Переходов между вершинами всего два: R и D.
Здесь можно заметить, что прийти к одним и тем же вершинам мы можем разными путями. Например, путь из (0,0) в (1,1) можно расписать и как RD ((0,0) -> (0,1) -> (1,1)), и как DR ((0,0) -> (1,0) -> (1,1)), но это два разных маршрута.
Однако при неизменном ценовом листе максимальная стоимость и оный маршрут в любой клетке поля значение строго определённое и неизменное во времени.
Это значит, что нам не нужно рассчитывать результат для одинаковых состояний больше одного раза, так как они будут совпадать.
Итак, для каждого состояния у нас есть два правила перехода. Рассчитывая максимальную стоимость маршрута для состояния (x,y) мы следуем алгоритму:
- Если можем идти вправо, рассчитываем параметры для этого маршрута
- Если можем идти вниз, рассчитываем параметры для этого маршрута
- Выбираем между путями, если можем идти, или стоим, если уже не можем
- К выбранному варианту добавляем параметры текущего состояния
Если такой алгоритм применить к состоянию (0,0), то дойдем до (N, M) и получим максимальную цену и маршрут.
import re
from typing import List
cache = {}
def calculate_max_way_price(x: int, y: int, prices: List[List[int]], m:int, n:int):
if (x, y) in cache:
return cache[(x, y)]
direction = ''
cost = prices[y][x]
x_cost, y_cost = -1, -1
x_way, y_way = '', ''
if x < m - 1:
x_cost, x_way = calculate_max_way_price(x + 1, y, prices, m, n)
if y < n - 1:
y_cost, y_way = calculate_max_way_price(x, y + 1, prices, m, n)
if not (x_cost < 0 and y_cost < 0):
if x_cost > y_cost:
cost += x_cost
direction = 'R' + x_way
else:
cost += y_cost
direction = 'D' + y_way
cache[(x, y)] = (cost, direction)
return cost, direction
MNtext = input('Enter N M: ')
MN = [int(x) for x in re.findall(r'd+', MNtext)]
if len(MN) != 2:
print("Input data error! It is not M and N")
exit(-1)
N, M = MN[0], MN[1]
MAX_STEP_PRICE = 100
data = input('Enter all numbers separated by spaces. You must type ' + str(M*N) + ' elements:')
data = [int(x) for x in re.findall(r'd+', data)]
if len(data) != N * M:
print("Input data error! Too few/many numbers")
exit(-2)
prices = []
for j in range(N):
prices.append(data[M*j:M*(j+1)])
print(calculate_max_way_price(0, 0, prices, M, N))