https://www.acmicpc.net/problem/17404
1번째 집과 마지막 n번째 집의 색이 달라야 함
- 1번 집의 색을 고정하고, 다음 집의 색을 차례대로 정해나감
ex) 1번 집을 R 색으로 칠하고, 다음 집들을 이전 집 색과 다른 2개 색 중 하나로 칠함 ...
=> 마지막 n번 집은 1번 집의 R 색 제외
이전 시리즈 문제 - 백준 1149, RGB 거리
- 본 문제는 이전 문제 RGB 거리에 조건 "1번 집과 마지막 n번 집의 색이 달라야 한다" 추가됨
- 백준 1149, RGB 거리 해설
int[][] dp
dp[i][j]
: [1]
~ [i]
번 집을 색칠, [i]
번 집은 [j]
색으로 색칠했을 때 최소 비용j
: Red 0, Green 1, Blue 2[1]
번 집과 마지막 [n]
번 집의 색이 달라야 함
=> [1]
번 집의 색을 R, G, B 중 1개로 고정하고, 나머지 [2]
번 ~ [n]
번 집의 색을 차례로 지정
초기식: [1]
번 집 색칠
=> 고정 색깔 제외, 나머지 2개 색은 INF
로 초기화
ex) [1]
번 집을 R [0]
로 색칠하면
dp[1][0] = costs[1][0]
, 나머지 2개 색 dp[1][1] = INF
, dp[1][2] = INF
점화식: [i]
번 집 색칠
=> 이전 집의 색과 다른 2개 색 중에서 최소값 선택
① [i]
번 집을 R [0]
으로 색칠하는 경우
dp[i][0] = min(dp[i-1][1], dp[i-1][2]) + costs[i][0]
② [i]
번 집을 G [1]
으로 색칠하는 경우
dp[i][1] = min(dp[i-1][0], dp[i-1][2]) + costs[i][1]
③ [i]
번 집을 B [2]
으로 색칠하는 경우
dp[i][2] = min(dp[i-1][0], dp[i-1][1]) + costs[i][2]
※ 마지막 [n]
번 집에서 [1]
번 집의 색은 제외
dp[n][1번 집의 색] = INF
int[][] dp
: DP 배열int
가능import java.io.*;
import java.util.StringTokenizer;
public class Main {
static int n; // 집 개수
static int[][] costs; // 각 집의 R, G, B 색칠 비용
static int[][] dp;
static final int INF = 1_000_000; // DP 배열 원소 최대값 (최대 누적 비용) = 10^3 x 10^3
static int minCost = INF; // 출력, 모든 집을 색칠하는 최소 비용
static void solution() {
for (int firstColor = 0; firstColor < 3; firstColor++) {
// [1]번 집의 색 고정
if (firstColor == 0) {
dp[1][0] = costs[1][0];
dp[1][1] = INF;
dp[1][2] = INF;
}
else if (firstColor == 1) {
dp[1][1] = costs[1][1];
dp[1][0] = INF;
dp[1][2] = INF;
}
else { // firstColor == 2
dp[1][2] = costs[1][2];
dp[1][0] = INF;
dp[1][1] = INF;
}
// [2] ~ [n]번째 집의 색
for (int i = 2; i <= n; i++) {
dp[i][0] = Math.min(dp[i-1][1], dp[i-1][2]) + costs[i][0];
dp[i][1] = Math.min(dp[i-1][0], dp[i-1][2]) + costs[i][1];
dp[i][2] = Math.min(dp[i-1][0], dp[i-1][1]) + costs[i][2];
// 마지막 [n]번 집의 색 != [1]번 집의 색
if (i == n)
dp[i][firstColor] = INF;
}
// 모든 집을 칠하는 최소 비용 minCost 갱신
for (int j = 0; j < 3; j++)
minCost = Math.min(minCost, dp[n][j]);
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in)
);
StringTokenizer st;
n = Integer.parseInt(br.readLine());
costs = new int[n + 1][3]; // [1][] ~ [n][] 사용
dp = new int[n + 1][3];
for (int i = 1; i <= n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < 3; j++)
costs[i][j] = Integer.parseInt(st.nextToken());
}
solution();
System.out.println(minCost);
}
}