내가 개발해볼게!!
[BOJ] 1149번: RGB거리 본문
https://www.acmicpc.net/problem/1149
문제
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
Try 1
재귀함수를 통해 맨뒤 집부터 앞으로 돌아나오면서 최솟값을 더해나가길 반복.
예제 1~4는 맞게 나오는데 예제 5에서 자꾸 다른 값이 나왔고 이유를 못 찾았다 ..
public class B1149_RGB거리 {
static int N;
static int[][] input;
static int[] ans;
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer token = new StringTokenizer(bf.readLine());
N = Integer.parseInt(token.nextToken()); // 집의 개수
input = new int[N][3];
ans = new int[3];
for(int i=0; i<N; i++){
token = new StringTokenizer(bf.readLine());
input[i][0] = Integer.parseInt(token.nextToken());
input[i][1] = Integer.parseInt(token.nextToken());
input[i][2] = Integer.parseInt(token.nextToken());
}
calcMin(N-1, 0, 0, 0);
calcMin(N-1, 0, 1, 1);
calcMin(N-1, 0, 2, 2);
System.out.println(Math.min(Math.min(ans[0], ans[1]), ans[2]));
}
static void calcMin(int count, int min, int selected, int s){ // count : 0 ~ N-1
if(count == 0){
min += input[0][selected];
System.out.println(input[0][selected]);
ans[s] = min;
System.out.println("ans[" + s + "] = " + min);
return;
}
if(selected == 0){
min += input[count][selected];
count--;
selected = input[count][1]>input[count][2] ? 2 : 1;
calcMin(count, min, selected, s);
}
else if(selected == 1){
min += input[count][selected];
count--;
selected = input[count][0]>input[count][2] ? 2 : 0;
calcMin(count, min, selected, s);
}
else if(selected == 2){
min += input[count][selected];
count--;
selected = input[count][0]>input[count][1] ? 1 : 0;
calcMin(count, min, selected, s);
}
}
}
Sol
동적 계획법 - 두 번째 집부터 차례대로 이전 집들 중 최솟값을 고르는 경우들을 더해나가면서 최종적인 최솟값을 찾는 방식
public class BOJ1149 {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer token = new StringTokenizer(bf.readLine());
int N = Integer.parseInt(token.nextToken()); // 집의 개수
int[][] input = new int[N][3]; // 1번 ~ N번 집을 세 가지 색상으로 칠하는 비용
for(int i=0; i<N; i++){
token = new StringTokenizer(bf.readLine());
input[i][0] = Integer.parseInt(token.nextToken()); // Red
input[i][1] = Integer.parseInt(token.nextToken()); // Green
input[i][2] = Integer.parseInt(token.nextToken()); // Blue
}
// input
for(int i=1; i<N; i++){
input[i][0] += Math.min(input[i-1][1], input[i-1][2]);
input[i][1] += Math.min(input[i-1][0], input[i-1][2]);
input[i][2] += Math.min(input[i-1][1], input[i-1][0]);
}
// operation
System.out.println(Math.min(Math.min(input[N-1][0], input[N-1][1]), input[N-1][2]));
// output
}
}
'Algorithm > BOJ' 카테고리의 다른 글
[BOJ] 9465번: 스티커 (0) | 2023.08.08 |
---|---|
[BOJ] 1495번: 기타리스트(java) (0) | 2023.08.04 |
[BOJ] 1446번: 지름길 (0) | 2023.07.28 |
[BOJ] 17615: 볼 모으기(Java) (0) | 2023.07.25 |
[BOJ] 1074번: Z(java) (0) | 2023.07.20 |