밍맹의 생각날 때 적는 블로그

[백준/11048] 이동하기 본문

알고리즘(Python)

[백준/11048] 이동하기

mingmaeng 2019. 11. 28. 21:19
문제
준규는 N×M 크기의 미로에 갇혀있다. 미로는 1 × 1 크기의 방으로 나누어져 있고, 각 방에는 사탕이 놓여 있다. 미로의 가장 왼쪽 윗 방은 (1, 1)이고, 가장 오른쪽 아랫 방은 (N, M)이다.
준규는 현재 (1, 1)에 있고, (N, M)으로 이동하려고 한다. 준규가 (r, c)에 있으면, (r+1, c), (r, c+1), (r+1, c+1)로 이동할 수 있고, 각 방을 방문할 때마다 방에 놓여있는 사탕을 모두 가져갈 수 있다. 또, 미로 밖으로 나갈 수는 없다.
준규가 (N, M)으로 이동할 때, 가져올 수 있는 사탕 개수의 최댓값을 구하시오.

 


문제는 다음과 같이 풀었다.

 

  • 각 위치마다 캔디의 개수가 들어 있는 candy_map과 크기가 동일하고 모든 요소가 0인 dp_map 2차원 리스트를
    만든다.
  • 리스트의 모든 요소를 탐색하면서 dp_map의 현재 위치(x, y)에 dp_map [x-1][y]와 dp_map [y][x-1] 중
    큰 값을 넣어준다.

  • 마지막으로 현재 위치와 동일한 위치의 candy_map에 있는 캔디의 개수를 추가해 준다.

 

이동 경로는 우측으로 한 칸, 아래로 한칸, 대각선으로 한칸 총 3가지 방식이 있지만 대각선으로 가는 경우는

생각하지 않는다. 왜냐하면 대각선으로 가는 경우는 우측으로 내려갔다 아래로 내려가거나, 아래로 내려갔다가 우측으로 내려가는 경우보다 절대 최댓값을 가질 수 없기 때문이다.

글로만 보면 이해하기 어려울 수 도 있으니 그림을 그려보자.

 


 

1 2 3 4
0 0 0 5
9 8 7 6

candy_map

먼저 각 위치에 캔디의 개수를 넣어 준 2차원 리스트 하나와

 

0 0 0 0
0 0 0 0
0 0 0 0

dp_map

크기는 동일하고 모든 요소가 0인 2차원 리스트 하나를 더 만들어 준다.

우리는 여기에다가 값을 넣어줄 것이고, 최종적인 출력 값도 이 리스트 요소 값을 출력할 것이다.

 

1 0 0 0
0 0 0 0
0 0 0 0

 

가장 처음의 인덱스인 dp_map [0][0] 에는 현재 위치의 캔디 개수만 들어간다.

 

1 1 + 2 = 3 0 0
0 0 0 0
0 0 0 0

 

그다음 위치에는 dp_map [x-1][y]와 dp_map [x][y-1] 값을 비교하는데 dp_map [x-1][y]의 값 밖에 없으므로

이에 해당하는 dp_map [0][0]과 candy_map [1][1]를 더한 값을 넣어준다.

 

1 3 6 10
1 3 9 15
10 0 0 0

 

좀 더 진행되었을 경우를 보자. 현재 dp_map [2][1]의 위치에 값을 넣을 차례다. 먼저 dp_map [2-1][1]과 dp_map [2][0]의 값 중 최댓값을 넣어준다.

 

1 3 6 10
1 3 9 15
10 10 0 0

 

dp_map [2-1][1]과 dp_map [2][0]의 값 중 최댓값인 10을 넣는다.

 

그다음 해당 위치와 동일한 위치의 candy_map 요소를 추가로 더해준다.

 

1 3 6 10
1 3 9 15
10 10+8 = 18 0 0

 

최종적으로 나오는 dp_map은 다음과 같다.

 

1 3 6 10
1 3 9 15
10 18 25 31

 

모든 탐색을 완료하고 가장 마지막 요소 값을 출력하면 끝!

 

코드는 다음과 같다

a,b = map(int,input().split()) # 행렬 크기 지정
candy_map = [[int(n) for n in input().split()] for _ in range(a)] # 캔디맵 생성
dp_map = [[0 for _ in range(b)] for _ in range(a)] # 각 인덱스에 최댓값을 넣어놓는 곳

for x in range(a) :
    for y in range(b):
        dp_map[x][y] = max(dp_map[x-1][y],dp_map[x][y-1]) #이전에 있던 좌표 값에서 큰 값을 가져옴
        dp_map[x][y] += candy_map[x][y] # 현재 위치와 동일한 위치의 캔디값을 더해준다.

print(dp_map[a-1][b-1])

다이내믹 프로그래밍을 이용해서 풀어보는 문제를 많이 경험해 보질 못 해서 생각하는데 어려움이 많았지만,

끈질기게 물고 늘어지다 보면 풀리긴 하는 걸 보니 신기방기 하다.

'알고리즘(Python)' 카테고리의 다른 글

[백준/1238/Python] 파티  (0) 2019.12.09
[백준/2573/Python] 빙산  (0) 2019.12.06
[백준/1316] 그룹 단어 체커 (Python)  (0) 2019.12.03
[백준/1890/Python] 점프  (0) 2019.12.01
[백준/10757] 큰 수 A+B  (0) 2019.11.28
Comments