문제
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보다 작거나 같은 자연수이다.
출력
첫째 줄에 모든 집을 칠하는 비용의 최솟값을 출력한다.
예제 입력 1
3
26 40 83
49 60 57
13 89 99
예제 출력 1
96
풀이 .
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int[][] rgb = new int[n][3];
int[][] dp = new int[n][3]; // dp[n][R or G or B] = n에 해당 색깔 놓을 수 있는 최소값
for(int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for(int j = 0; j < 3; j++) {
rgb[i][j] = Integer.parseInt(st.nextToken());
}
}
dp[0][0] = rgb[0][0];
dp[0][1] = rgb[0][1];
dp[0][2] = rgb[0][2];
for(int i = 1; i < n; i++) {
dp[i][0] = Math.min(dp[i-1][1], dp[i-1][2]) + rgb[i][0];
dp[i][1] = Math.min(dp[i-1][0], dp[i-1][2]) + rgb[i][1];
dp[i][2] = Math.min(dp[i-1][0], dp[i-1][1]) + rgb[i][2];
}
int ans = Math.min(dp[n-1][0], Math.min(dp[n-1][1], dp[n-1][2]));
System.out.println(ans);
}
}
대놓고 DP문제인데.. 보자마자 DP를 떠올렸어야 하는 문제인데 그러지 못했다.
처음에는 모든 조합을 구해서 조건을 만족하는지 검사해볼까 했지만 무조건 시간 초과가 나는 방법이다.
3^N개의 조합이 나오게 되는데 N이 최대 1000이기 때문에 최대 3^1000가지의 조합
거기다 조건 검사 한 번에 O(N) 시간.. 이건 무조건 시간 초과다.
결국 어떤 알고리즘이 사용되는지 확인했고 어려운 문제는 아니라서 DP를 확인하자마자 바로 풀어낼 수 있었다.
조건이 3개나 존재하지만 결국 다 같은 말이다. (일부러 헷갈리게 하려고 같은 말을 다른 식으로 여러 번 써놓은 건가?)
그냥 나와 인접하는 양 옆의 집과 다른 색을 가져야 한다는 얘기다.
집을 하나 놓을 때마다 이전 집과 다른 색들 중에서 고르면 되는 것이다.
DP에 저장하는 값은 "dp[n][color] = n번째 집에 color 색을 놓았을 때 가능한 최소값" 이다.
DP 배열을 1차원으로 할까도 생각해봤지만 그럼 다른 색을 놓아야 하는 조건을 검사하는 게 번거로워진다. 그냥 2차원을 사용하자.
'알고리즘 문제 > 백준 온라인 저지' 카테고리의 다른 글
[BOJ] 1943 - 동전 분배 JAVA (0) | 2021.02.28 |
---|---|
[BOJ] 12865 - 평범한 배낭 JAVA (0) | 2021.02.28 |
[BOJ] 1662 - 압축 JAVA (0) | 2021.02.25 |
[BOJ] 14719 - 빗물 JAVA (0) | 2021.02.25 |
[BOJ] 2304 - 창고 다각형 JAVA (0) | 2021.02.24 |