이모저모

동적 계획법 - bottom-up, top-down (최소 에너지로 돌다리 건너기) 본문

coding/알고리즘,자료구조

동적 계획법 - bottom-up, top-down (최소 에너지로 돌다리 건너기)

Jeo 2022. 1. 31. 14:55

동일한 문제에 대해 bottom-up, top-down 두 가지 접근을 연습해보기!

1. 손계획

2. 코드

n = 3
stones = [
    [3, 3, 5],
    [2, 3, 4],
    [6, 5, 2]
]

record = [[0] * n for _ in range(n)]
record[0][0] = stones[0][0]

##### bottom-up 풀이
for i in range(n):
    for j in range(n):
        # 0행의 경우 참고할 위칸은 없으므로, 바로 왼쪽 칸만 참고하면 된다.
        # 그리고 j까지 0인 경우는 시작점이고 답을 미리 정해놓았으므로 따로 계산하지 않고 pass
        if i == 0:
            if j == 0:
                pass
            else:
                record[i][j] = record[i][j-1] + stones[i][j]

        else:
            # 0 행은 아니면서 0열인 곳에 있는 칸은, 바로 위쪽 칸만 참고하면 된다.
            if j == 0:
                record[i][j] = record[i-1][j] + stones[i][j]
            # 맨 위의 행와 맨 왼쪽의 열이 모두 아닌 칸들의 경우, 왼쪽과 위에 인접한 칸들로부터 그들의 기록을 살펴보고
            # 그 중 더 적은 에너지를 들인 경로를 택할 것이므로, 더 적은 기록에 자신의 높이까지 더하여 자신까지 오는데 필요한 최소 에너지를 기록한다.
            else:
                record[i][j] = min(record[i-1][j], record[i][j-1]) + stones[i][j]

print(record[n-1][n-1])


##### top-down 풀이
def DFS(i, j):
    # 0행 0열의 경우 바로 자신의 높이만큼만 리턴해준다.
    if i == 0 and j == 0:
        return stones[0][0]
    # 0행의 경우, 자신의 왼쪽 칸만 참고하여, 그 친구에 자신의 높이를 더한만큼 리턴한다.
    elif i == 0:
        record[i][j] = DFS(i, j-1) + stones[i][j]

    # 0열의 경우, 자신의 위쪽 칸만 참고하여, 그 친구에 자신의 높이를 더한만큼 리턴한다.
    elif j == 0:
        record[i][j] = DFS(i-1, j) + stones[i][j]
    
    else:
    # 0행도 0열도 아닌 경우, 자신의 왼쪽과 위의 칸이 제시할 최소 에너지들 중 더 min 인 값을 채택하고, 자신의 높이를 더하여 리턴한다.
    # 혹시라도 왼/위에 대해서 미리 구해둔 계산 결과가 있다면, 그 칸에 대해서는 재귀 호출하지 않고 record 에서 참고하여 return.
        if record[i-1][j] != 0 and record[i][j-1] != 0:
            record[i][j] = min(record[i-1][j], record[i][j-1]) + stones[i][j]
            
        elif record[i-1][j] != 0:
            record[i][j] = min(record[i-1][j], DFS(i, j-1)) + stones[i][j]
            
        elif record[i][j-1] != 0:
            record[i][j] = min(DFS(i-1, j), record[i][j-1]) + stones[i][j]
            
        else:
            record[i][j] = min(DFS(i-1, j), DFS(i, j-1)) + stones[i][j]

    return record[i][j]
    
print(DFS(n-1, n-1))
Comments