새벽코딩

[백준] [1149] RGB거리 (JAVA) (DP) 본문

알고리즘

[백준] [1149] RGB거리 (JAVA) (DP)

J 코딩 2023. 5. 4. 17:50
반응형

https://www.acmicpc.net/problem/1149

 

1149번: RGB거리

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

www.acmicpc.net



문제

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보다 작거나 같은 자연수이다.

출력

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


※ JAVA 코드(RGB거리)

import java.io.*;
import java.util.*;

public class Main {
    static int[][] dp;
    static int[][] cost;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = null;
        // 집의 수
        Integer N = Integer.parseInt(br.readLine());

        // 초기화
        dp = new int[N][3];
        cost = new int[N][3];

        // 집의 수만큼 입력
        for(int h = 0; h < N; h++){
            st = new StringTokenizer(br.readLine());
            // 색상 값 {0: Red, 1: Green, 2: Blue}
            for(int c = 0; c < 3; c++){
                // 초기 값 (Red or Green or Blue)
                dp[h][c] = 0;
                // 초기 비용 0원부터 시작
                cost[h][c] = Integer.parseInt(st.nextToken());
            }
        }
        // 첫번째 집 Red
        dp[0][0] = cost[0][0];
        // 첫번째 집 Green
        dp[0][1] = cost[0][1];
        // 첫번째 집 Blue
        dp[0][2] = cost[0][2];

        int result = Math.min(dp(N-1, 0), dp(N-1, 1));
        result = Math.min(result, dp(N-1, 2));

        System.out.println(result);
    }

    static int dp(int h, int c){
        // 아직 값이 없을때
        if(dp[h][c] == 0){
            switch (c){
                case 0:
                    dp[h][c] = Math.min(dp(h-1, 1), dp(h-1, 2)) + cost[h][0];
                    break;
                case 1:
                    dp[h][c] = Math.min(dp(h-1, 0), dp(h-1, 2)) + cost[h][1];
                    break;
                case 2:
                    dp[h][c] = Math.min(dp(h-1, 0), dp(h-1, 1)) + cost[h][2];
                    break;
            }
        }
        return dp[h][c];
    }
}

※ 생각정리 (RGB거리)

전형적인 DP문제

맨 처음 집의 색상을 정한후 나올 수 있는 집의 경우를 생각해본다.

1. N이 빨간집인경우

- N-1은 녹색이거나 파란색일 수 있다.

- 두 경우중 더 작은 비용의 값을 구하고 N이 빨간집인 경우의 가중치를 더한다.

- dp[h][c] = Math.min(dp(h-1, 1), dp(h-1, 2)) + cost[h][0];

2. N이 녹색인 경우와 파란색인 경우는 위와 동일하다.

 

중요한 점은 N-1을 넣고 재귀를 돌며 계속해서 다음 값을 합해나간다.

 

 

-새벽코딩-

반응형
Comments