본문 바로가기
알고리즘 문제 풀이

[백준 1149] RGB 거리

by 다빈치코딩 2024. 12. 7.

목차

    반응형

    RGB 거리(1149)

    문제 출처 : https://www.acmicpc.net/problem/1149

    N개의 집에 빨강, 파랑, 초록색으로 지붕을 칠해야 하는 문제입니다. 이 때 비용이 최소가 되고, 지붕의 색이 겹쳐지지 않아야 합니다.

    어떤 지붕이 빨간색이면 그 앞과 뒤의 집은 빨간색이면 안됩니다. 이렇게 모든 지붕에 색을 칠할 때 최소값을 구하는 문제 입니다. 그럼 다음과 같은 함수를 만들 수 있습니다.

    solve(n, c)

    이 함수는 n번째 집의 지붕에 c라는 색으로 칠했을 때 드는 최소 비용 입니다. c는 빨강은 0, 파랑은 1, 초록은 2로 입력받도록 합니다.

    코드 작성하기

    간단한 DP문제이기 때문에 바로 코드를 작성해 보겠습니다.

    입력 받기

    N = int(input())
    
    cost = [[0, 0, 0]]
    for _ in range(N):
        cost.append(list(map(int, input().split())))
    

    먼저 집의 개수 N을 입력 받습니다. 숫자를 계산하기 쉽게 하기 위해 0번째 집을 만들어 [0, 0, 0]으로 넣었습니다. 다음으로 빨강, 파랑, 초록색으로 지붕 색깔을 칠할 때 드는 비용을 cost에 입력 합니다. 숫자가 0부터 시작하는 것이 익숙하다면 굳이 초기값 [0, 0, 0]을 넣어 길이를 맞추어 줄 필요가 없습니다.

    출력하기

    rst = min(solve(N, 0), solve(N, 1), solve(N, 2))
    print(rst)
    

    N개의 집이 존재하고, 각각 빨강, 파랑, 초록색으로 칠했을 경우 각각의 최소 비용을 얻어 이 중 가장 작은 값을 출력하도록 합니다.

    solve 함수 1

    그럼 이 문제의 핵심인 solve 함수를 구현해 보겠습니다.

    def solve(n, c):
        rst = 10e6
        for i in range(3):
            if i == c:
                continue
            rst = min(rst, solve(n - 1, i))
            
        return rst + cost[n][c]
    

    지붕의 종류는 세가지이기 때문에 반복문을 세 번 반복합니다. n - 1번째는 바로 앞의 집입니다. 이 때 같은 색깔의 지붕이 연속으로 있으면 안됩니다. 따라서 현재 지붕색 c와 n - 1번째의 지붕의 색인 i값이 같으면 continue로 넘어갑니다. 그렇게 자신과 같은 색을 제외한 나머지 두 지붕의 색의 최소값을 rst에 저장합니다. 최소값을 구하기 위해 초기값은 10의 6승으로 하였습니다. 집의 개수 최대가 1,000이고 비용의 최대가 1,000이기 때문에 초기값은 1,000 * 1,000인 10의 6승으로 합니다.

    마지막으로 rst의 값은 n - 1 번째 집까지의 최소 비용 입니다. 여기에 n번째 집의 지붕 색깔인 c의 가격을 더해줍니다. n번째 지붕의 색은 cost[n][c]에 있기 때문에 최종적으로 리턴해주어야 하는 값은 rst + cost[n][c]가 됩니다.

    solve 함수 2

    위의 코드는 종료조건, 메모이제이션 처리가 없습니다. 이 두가지를 추가해 주겠습니다.

    dp = [[0] * 3 for _ in range(N + 1)]
    # solve(n, c) : n번째 집이 c라는 컬러로 칠했을 때 최소 rkqt
    def solve(n, c):
        # 종료조건
        if n == 1:
            return cost[n][c]
        
        if dp[n][c]:
            return dp[n][c]
    
        rst = 10e6
        for i in range(3):
            if i == c:
                continue
            rst = min(rst, solve(n - 1, i))
            
        dp[n][c] = rst + cost[n][c]
        return dp[n][c]
    

    먼저 종료 조건입니다. n의 길이가 1이 되었을 때 현재 지붕의 색깔에 맞게 비용을 지불 합니다. 현재 색깔의 지붕 가격인 cost[n][c]를 리턴하면 됩니다.

    다음으로 메모이제이션 처리 입니다. dp[n][c]를 확인해서 기존 값이 있으면 해당 값을 리턴하고, 없으면 계산을 합니다. 계산으로 최소값을 구하면 dp[n][c]에 넣어줍니다.

    전체 코드

    전체 코드를 확인해 보겠습니다.

    N = int(input())
    
    cost = [[0, 0, 0]]
    for _ in range(N):
        cost.append(list(map(int, input().split())))
    
    dp = [[0] * 3 for _ in range(N + 1)]
    # solve(n, c) : n번째 집이 c라는 색으로 칠했을 때 최소값 리턴
    def solve(n, c):
        # 종료조건
        if n == 1:
            return cost[n][c]
        
        # 메모이제이션
        if dp[n][c]:
            return dp[n][c]
    
        rst = 10e6
        for i in range(3):
            if i == c:
                continue
            rst = min(rst, solve(n - 1, i))
            
        dp[n][c] = rst + cost[n][c]
        return dp[n][c]
    
    rst = min(solve(N, 0), solve(N, 1), solve(N, 2))
    print(rst)
    
    반응형

    '알고리즘 문제 풀이' 카테고리의 다른 글

    [백준 7573] 고기잡이  (0) 2025.01.27
    [백준 10211] Maximum Subarray  (0) 2025.01.19
    [백준 24552] 올바른 괄호  (2) 2024.11.27
    [백준 2504] 괄호의 값  (0) 2024.11.26
    [백준 22341] 사각형 면적  (0) 2024.11.25