[Kotlin] 백준(BOJ) 1149 RGB거리

2026. 2. 3. 23:22·Problem Solving

문제 전문은 아래 버튼을 눌러 확인하실  수 있습니다.

더보기

문제

RGB거리에는 집이 N개 있다. 거리는 선분으로 나타낼 수 있고, 1번 집부터 N번 집이 순서대로 있다.

집은 빨강, 초록, 파랑 중 하나의 색으로 칠해야 한다. 각각의 집을 빨강, 초록, 파랑으로 칠하는 비용이 주어졌을 때, 아래 규칙을 만족하면서 모든 집을 칠하는 비용의 최솟값을 구해보자.

  • 1번 집의 색은 2번 집의 색과 같지 않아야 한다.
  • N번 집의 색은 N-1번 집의 색과 같지 않아야 한다.
  • i(2 ≤ i ≤ N-1)번 집의 색은 i-1번, i+1번 집의 색과 같지 않아야 한다.

입력

첫째 줄에 집의 수 N(2 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 각 집을 빨강, 초록, 파랑으로 칠하는 비용이 1번 집부터 한 줄에 하나씩 주어진다. 집을 칠하는 비용은 1,000보다 작거나 같은 자연수이다.

 

출력

첫째 줄에 모든 집을 칠하는 비용의 최솟값을 출력한다.

 

예제 입출력

 

문제 해설

문제를 다시 간단하게 요약하자면, R, G, B 3가지의 색을 최종 비용이 최소가 되고, 이웃한 집끼리 색깔이 같지 않으게되도록 각 집에 배정하는 것이다. 

전형적인 다이나믹 프로그래밍 문제의 유형 중 하나라고 할 수 있겠다. 현재 고려하고 있는 집에 어떤 색을 배정한다고 할 때 그 배정이 최종적으로 최선일지 아닐지 알기 위해서는 맨 끝까지 탐색해야 결정할 수 있다. 

 

때문에 이 탐색을 최대한 빠르고 쉽게 해결하기 위해서는 문제를 나눠 생각하여야 한다. 이를 생각하는 방법에는 재귀 알고리즘을 사용하는 탑 다운 메모이제이션과, 단순히 선형 자료구조를 채우면서 진행하는 바텀 업 타뷸레이션 방식이 있는데 바텀 업 방식으로 설명하도록 하겠다.

 

예제 입출력 1을 기준으로 생각해봤을 때

1번째집의 최솟값은 단순히 R, G, B의 비용 중 최소인 값을 취하면 되므로, R, 26이다.  

하지만 2번째 집까지 포함하는 최솟값을 생각해봤을 때, 1번째 집을 R로 칠하면 안될 수 있다. 이전 집에서 선택한 색상은 다음 집에서 선택할 수 없기 때문이다.

 

예제에는 그렇지 않지만 만약 2번집의 R 색칠 비용이 1이라면 사실 1번째 집에서 비용 40의 G를 색칠하고 2번째 집에서 비용 1만 지불하면 해당 값이 최소이다. 

 

때문에 단순히 최솟값만 취하는 그리디적인 사고가 아닌, 최솟값 후보들을 전부 기록해 뒀다가 실제로 대입해봐야한다. 

여기서 최솟값 후보는 결국 다음을 의미한다. 

이전 집의 각 색깔별 최솟값 + 현재 집의 각 색깔 코스트

위 내용들을 종합하여 다음과 같은 과정으로 점화식을 도출해봤다. 

기록은 DP 2차원 배열에, R: 0, G: 1. B: 2로 인덱싱 했다. 

 

1. 기저값 설정:

첫 번쨰 집은 이전에 칠한 집이 없으므로 각 색칠 비용 자체가 최소 비용이 됨

$DP[0][0] = cost[0][0]$

$DP[0][1] = cost[0][1]$

$DP[0][1] = cost[0][2]$

 

2. N번째 집을 빨간색으로 칠할 경우

앞집은 초록이나 파랑이어야 하므로 

$DP[i][0]=min(DP[i−1][1],DP[i−1][2])+Cost[i][0]$ 

 

3. N번째 집을 초록색으로 칠할 경우

앞집은 빨강이나 파랑이어야 하므로

$DP[i][0]=min(DP[i−1][0],DP[i−1][2])+Cost[i][1]$ 


4. N번째 집을 파란색으로 칠할 경우

앞집은 빨강이거나 초록이어야 하므로

$DP[i][0]=min(DP[i−1][0],DP[i−1][2])+Cost[i][2]$ 

 

5. 마지막 집까지 진행한 뒤 마지막 집의 최소 비용 후보 중 최소값을 선정하면 된다. 

$Answer=min(DP[N−1][0],DP[N−1][1],DP[N−1][2])$

소스 코드

import kotlin.math.min

fun main() {
    val n = readln().toInt()
    val costs = Array(n) { IntArray(3) }

    for (i in 0 until n) {
        val line = readln().split(" ").map { it.toInt() }
        costs[i][0] = line[0] // 빨강 비용
        costs[i][1] = line[1] // 초록 비용
        costs[i][2] = line[2] // 파랑 비용
    }

    // dp[i][0]: i번째 집까지 칠했고, i번째 집이 빨강일 때의 최소 누적 비용
    val dp = Array(n) { IntArray(3) }

    // 첫 번째 집 초기화
    dp[0][0] = costs[0][0]
    dp[0][1] = costs[0][1]
    dp[0][2] = costs[0][2]

    for (i in 1 until n) {
        // 현재 집(i)을 빨강으로 칠하려면, 이전 집(i-1)은 초록이나 파랑이어야 함
        dp[i][0] = costs[i][0] + min(dp[i-1][1], dp[i-1][2])

        // 현재 집(i)을 초록으로 칠하려면, 이전 집(i-1)은 빨강이나 파랑이어야 함
        dp[i][1] = costs[i][1] + min(dp[i-1][0], dp[i-1][2])

        // 현재 집(i)을 파랑으로 칠하려면, 이전 집(i-1)은 빨강이나 초록이어야 함
        dp[i][2] = costs[i][2] + min(dp[i-1][0], dp[i-1][1])
    }

    // 마지막 집(n-1)에 저장된 값 중 최솟값 출력
    val result = min(dp[n-1][0], min(dp[n-1][1], dp[n-1][2]))
    println(result)
}

 

 

 

시간 복잡도

상수번 연산을 수행하는 반복문이 2개이므로 $O(2N)$, 즉 $O(N)$ 이라고 할 수 있다. 

 

'Problem Solving' 카테고리의 다른 글

[Kotlin] 백준(BOJ) 9461 파도반 수열  (0) 2026.02.06
[Kotlin] 백준(BOJ) 11053 가장 긴 증가하는 부분 수열  (1) 2026.02.04
[Kotlin] 백준(BOJ) 13305 주유소  (0) 2026.01.31
[Kotlin] 백준(BOJ) 12904 A와 B  (1) 2026.01.30
[Kotlin] 백준(BOJ) 1541 잃어버린 괄호  (0) 2026.01.29
'Problem Solving' 카테고리의 다른 글
  • [Kotlin] 백준(BOJ) 9461 파도반 수열
  • [Kotlin] 백준(BOJ) 11053 가장 긴 증가하는 부분 수열
  • [Kotlin] 백준(BOJ) 13305 주유소
  • [Kotlin] 백준(BOJ) 12904 A와 B
Kirbyyy
Kirbyyy
개인적인 일상과 회고를 기록하는 블로그입니다.
  • Kirbyyy
    커브볼의 생존일지
    Kirbyyy
  • 전체
    오늘
    어제
    • 분류 전체보기 (53)
      • 우아한테크코스 (8)
      • 프로덕트 빌드 (0)
      • Problem Solving (20)
      • C++ (0)
      • Kotlin (19)
      • Java (3)
      • CS (2)
        • AI (2)
      • 취미생활 (0)
        • 서평 (0)
        • 프라모델 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백준 33272
    C++
    BFS
    백준 RGB 거리
    백준 11123
    백준
    백준 16174
    백준 파도반 수열
    우테코 8기
    백준 알고리즘
    그리디 알고리즘
    백준 31575
    분할 정복
    백준 1356
    너비 우선 탐색
    다이나믹 프로그래밍
    백준 연속 합
    백준 16173
    ProblemSolving
    Problem Solving
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
Kirbyyy
[Kotlin] 백준(BOJ) 1149 RGB거리
상단으로

티스토리툴바