

오른쪽으로 한 칸, 아래로 한 칸, 오른쪽 아래 대각선으로 한 칸 중 하나의 방법으로 움직일 수 있습니다.현재 칸에서 어디로 갈 수 있는가? 보다 현재 칸으로 어떻게 올 수 있는가?를 기준으로 생각하는 게 더 쉽습니다.

즉 현재 칸까지 오면서 모은 사탕의 개수 = 이전 칸까지 오면서 모은 사탕의 개수 + 현재 칸의 사탕이 성립합니다.
왼쪽에서 접근한다.
위에서 접근한다.
왼쪽 위에서 대각선으로 접근한다.

그렇다면 ☆에 최대한 많은 사탕을 가지고 접근하는 방법은 어떻게 될까요?

다음과 같다면 우리는 15에서 ☆로 가는 게 가장 현명한 방법일 것입니다.

N,M = list(map(int,input().split(' ')))
#미로를 구현합니다
board = []
for _ in range(N):
board.append(list(map(int,input().split(' '))))
# (r+1,c),(r,c+1),(r+1,c+1)로 이동할 수 있다는 건 (x,y)에 (x-1,y),(x,y-1),(x-1,y-1)에서 도달할 수 있다는 걸 의미합니다.
direction = [[-1,0],[0,-1],[-1,-1]]
#모든 미로칸을 순회합니다
for i in range(N):
for j in range(M):
lst = [] # 3방향에서 들어오는 값을 비교하기 위해 일시적으로 lst라는 곳에 담아두겠습니다. 해당 변수는 미로칸이 바뀔때마다 초기화됩니다.
for d in direction:
id_ = i+d[0]
jd_ = j+d[1]
if 0<=id_<N and 0<=jd_<M: #미로를 벗어나지 않는 값들만 고려합니다
lst.append(board[id_][jd_])
if lst: #lst속에 값이 존재한다면
board[i][j] = board[i][j]+ max(lst) #해당 판으로 오면서 모을 수 있는 최대 사탕의 수 = 3가지 경우의 수 중 가장 많은 사탕을 모은 경우 + 해당 판에 놓인 사탕
print(board[N-1][M-1])