문제풀이
(r, c)까지 왔을 때 가질 수 있는 사탕의 최댓값을 dp[r][c]이라 하면, 점화식은 다음과 같이 쓸 수 있다.
dp[r][c] = max(dp[r][c-1], dp[r-1][c]
즉, (r,c) 까지 오는 방법은 같은 행의 왼쪽 열에서 오거나, 이전 행의 같은 열에서 오는 두가지 방법이 있다.
따라서 모든 r을 0부터 n까지 반복한 후, dp[n][m]을 반환하면 된다.
Python Code
1
2
3
4
5
6
7
8
9
10
11
|
import sys
n,m = map(int,sys.stdin.readline().split())
dp = list(map(int,sys.stdin.readline().split()))
for j in range(1,m):
dp[j] = dp[j-1]+dp[j]
for i in range(1,n):
maze = list(map(int,sys.stdin.readline().split()))
dp[0]+=maze[0]
for j in range(1,m):
dp[j] = max(dp[j-1]+maze[j],dp[j]+maze[j])
print(dp[-1])
|
cs |
Line 4 : 첫번째 행에 대한 연산이다.
Line 6 : 두번째 행 이후에 대한 연산이다.
비효율적이었던 풀이
풀이 설명을 보면 dp가 n*m 인 행렬이지만, 위의 코드는 길이가 m인 배열이다. 처음에는 maze 행렬을 모두 받아서 가진 상황에서 풀이를 했는데, 시간이 다른 풀이들에 비해 오래걸렸다. 좀 더 효율적으로 수정한 코드가 위의 코드이며, maze를 한줄씩 받으며 즉시 처리하는 식으로 바꿨더니 시간이 1632ms에서 720ms로 절반이상 줄었다. 메모리 역시 절반 이상 줄일 수 있었다.
아래는 첫 풀이이다. 위의 코드와는 달리 bfs를 이용하여 0,0 부터 m,n까지 dp 행렬을 채워나갔으며, 위에서 말했듯, maze를 모두 받고 시작했고, dp는 모든 요소가 0인 m*n 행렬로 초기화하였다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
import collections
import sys
def summation(maze):
ans = 0
for m in maze:
ans += sum(m)
return ans
n,m = map(int,sys.stdin.readline().split())
maze = []
for i in range(n):
maze.append(list(map(int,sys.stdin.readline().split())))
if n < 2 or m < 2:
print(summation(maze))
else:
dp = [[0 for i in range(m)] for j in range(n)]
dp[0][0]=maze[0][0]
q = collections.deque()
q.append([1,0])
q.append([0,1])
while q:
row,col = q.popleft()
if col == 0 : dp[row][col]=dp[row-1][col]+maze[row][col]
elif row == 0 : dp[row][col]=dp[row][col-1]+maze[row][col]
else : dp[row][col] = max(dp[row-1][col]+maze[row][col], dp[row][col-1]+maze[row][col])
if row == n and col == m : break
if col == 0 and row < n-1 :
q.append([row+1,col])
if col < m-1 :
q.append([row,col+1])
print(dp[-1][-1])
|
cs |
문제 링크
11048번: 이동하기
준규는 N×M 크기의 미로에 갇혀있다. 미로는 1×1크기의 방으로 나누어져 있고, 각 방에는 사탕이 놓여져 있다. 미로의 가장 왼쪽 윗 방은 (1, 1)이고, 가장 오른쪽 아랫 방은 (N, M)이다. 준규는 현재 (1, 1)에 있고, (N, M)으로 이동하려고 한다. 준규가 (r, c)에 있으면, (r+1, c), (r, c+1), (r+1, c+1)로 이동할 수 있고, 각 방을 방문할 때마다 방에 놓여져있는 사탕을 모두 가져갈 수 있다. 또, 미로 밖으
www.acmicpc.net
'알고리즘 > 백준' 카테고리의 다른 글
백준 11657 타임머신 / 벨만 포드 알고리즘 (0) | 2020.04.11 |
---|---|
백준 1002 터렛 (0) | 2020.04.09 |
백준 10610 30 (0) | 2020.03.28 |
백준 2436 공약수 (0) | 2020.03.24 |
백준 2559 수열 (0) | 2020.03.23 |