# 진우의 달 여행 import sys input = sys.stdin.readline def solution(): n, m = map(int, input().rstrip().split()) direction = [-1, 0, 1] grid = [list(map(int, input().rstrip().split())) for _ in range(n)] dp = [[[0]*3 for _ in range(m)] for _ in range(n)] for i in range(m): for j in range(len(direction)): dp[0][i][j] = grid[0][i] for i in range(1, n): for j in range(m): for k in range(len(direction)): if j == 0: dp[i][j][k] = min([dp[i-1][j+direction[h]][h] for h in range(len(direction)) if h != k and direction[h] != -1]) + grid[i][j] elif j == m-1: dp[i][j][k] = min([dp[i-1][j+direction[h]][h] for h in range(len(direction)) if h != k and direction[h] != 1]) + grid[i][j] else: dp[i][j][k] = min([dp[i-1][j+direction[h]][h] for h in range(len(direction)) if h != k]) + grid[i][j] print(min([min(dp[n-1][j]) for j in range(m)])) return solution() """ 풀이(2) -> dp 걸린 시간: 45분 시간 복잡도: n*m*3(방향)으로 된 3차원 dp를 채우는데, 방향을 채울 때 본인을 제외한 방향들의 최소를 구하기 때문에 *2를 해서 (n*m*3*2)이다. 해설: 다른 풀이에서 DP가 있다는 것을 알게되어서 두 번째 풀이를 진행했다. i, j, k는 행, 열, 이전 방향이라고 할때, dp[i][j][k]를 구하면 i-1번째 행에서 direction[k]방향을 제외한 j열의 값들 중에 최소와 현재 행렬 값(grid[i][j])의 합이다. 즉 [i][j][0]은 direction[0]이 -1방향이므로 [i-1][j-1]에서 값을 가져오는데 [i-1][j-1][0]을 제외한 값들 중에 최소를 가져온다. """ """ 풀이(1) -> dfs 걸린 시간: 35분 시간 복잡도: 첫 행에서 갈 수 있는 경우의 수는 3이고 마지막 행을 제외한 행에서 경우의 수는 2이므로 3*2^(n-2) 이다. 이것을 열 개수만큼 반복해야 하므로 3*2^(n-2)*m 이다. 사실상 O(2^n * m)이라서 말이 안되는 시간복잡도이지만 조건때문에 그냥 했다. 해설: 2 <= n, m <= 6인걸 봐서는 모든 경우의 수를 확인해보라는 것 같다. (3 * 2^4) * 6 개이므로 얼마 안된다. dfs의 기저를 depth가 n-1보다 클때, 즉 마지막 행에 도달했을 때로 잡았고, 지금까지 더해온 total에 마지막 grid 값을 더한 뒤 result 리스트에 넣고 마지막에 min을 구해서 출력하도록 하였다. 이전에 어디로 갔는지도 계속 가져가며 갈 수 있는 전체 방향에서 이전에 간 방향 빼고, 열 밖으로 나가는 것까지 빼면 된다. total을 어떻게 계속 갱신할지 dfs에 선언하면 꼬일 것 같아서 고민했는데 그냥 인자로만 계속 넘기면 괜찮은 것 같다. """ # result = [] # def solution(): # n, m = map(int, input().rstrip().split()) # grid = [list(map(int, input().rstrip().split())) for _ in range(n)] # dx = [-1, 0, 1] # dy = [1, 1, 1] # def dfs(depth, col, before, total): # if depth >= n-1: # total += grid[depth][col] # result.append(total) # return # for i in range(3): # if i == before or col+dx[i] >= m or col+dx[i] < 0: # continue # dfs(depth+dy[i], col+dx[i], i, total+grid[depth][col]) # return total # for i in range(m): # dfs(0, i, -1, 0) # print(min(result)) # return # solution()