BOJ
[Python 3] BOJ - 1149 "RGB 거리"
PeiSea
2020. 3. 11. 22:18
# 문제 링크 : https://www.acmicpc.net/problem/1149
1149번: RGB거리
첫째 줄에 집의 수 N(2 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 각 집을 빨강, 초록, 파랑으로 칠하는 비용이 1번 집부터 한 줄에 하나씩 주어진다. 집을 칠하는 비용은 1,000보다 작거나 같은 자연수이다.
www.acmicpc.net
# 풀이 :
그리디 알고리즘으로 자칫 접급할 수 있지만, 반례를 쉽게 찾을 수 있다. 따라서 이 문제는 그리디 알고리즘으로는 최적해를 찾을 수 없다. 따라서 다이나믹 프로그래밍으로 접근해야 한다. 개인적으로 문제의 핵심은 비록 처음과 끝이 아닌 경우에는 양 옆집과 다른색이 되어야 하지만, 결론적으로 바로 앞집에 의해서만 해당 집의 색깔이 결정된다는 점이다.
예시)
위의 그림 1에서는 설명을 위해 첫번째 집은 빨강, 두번째 집은 초록으로 임의로 설정하였다. 따라서 현재 칠애햐 할 집에 가능한 색깔, 즉 ?는 파랑 혹은 빨강이 되어야 한다. 따라서 우리는 어떤 집을 칠할 때 그 집에 쓸 수 있는 색깔은 바로 앞집에서 쓴 색깔이 아닌 색깔은 모두 가능하다는 것이다.
따라서 일반화를 거친다면, 점화식은 아래와 같다.
따라서 DP 테이블은 1차원이 아니라, N x 3인 2차원 배열이 되어야 한다.
# 코드
import sys
n = int(sys.stdin.readline())
# N x 3 DP Table 생성
# table[i][0] = i번째 집을 빨강으로 칠하는 경우
# table[i][1] = i번째 집을 파랑으로 칠하는 경우
# table[i][2] = i번째 집을 초록으로 칠하는 경우
table = [[0,0,0] for _ in range(n)]
for i in range(n):
temp = list(map(int, sys.stdin.readline().split()))
if i == 0:
table[0] = temp
else:
# 점화식을 통한 DP Table 채우기
table[i][0] = min(table[i - 1][1], table[i - 1][2]) + temp[0]
table[i][1] = min(table[i - 1][0], table[i - 1][2]) + temp[1]
table[i][2] = min(table[i - 1][0], table[i - 1][1]) + temp[2]
# 빨강, 초록, 파랑으로 칠하는 경우 중 최소값 출력
print(min(table[n - 1]))