알고리즘/백준

공부 145일차: 백준 17404번 RGB거리 2 자바 java

김발자~ 2022. 12. 22. 21:02
반응형

17404 RGB거리 2

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

 

17404번: RGB거리 2

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

www.acmicpc.net

 

 


백준 17404번 문제 RGB거리 2


문제


 

 

 


과정 생각해보기 & 오답


 

https://gimbalja.tistory.com/m/260

 

공부 134일차: 백준 1149번 RGB거리 자바 java

1149 RGB거리 https://www.acmicpc.net/problem/1149 1149번: RGB거리 첫째 줄에 집의 수 N(2 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 각 집을 빨강, 초록, 파랑으로 칠하는 비용이 1번 집부터 한 줄에

gimbalja.tistory.com

 

이 문제에 추가 조건이 붙은 문제다

 

  • 1번 집의 색은 2번, N번 집의 색과 같지 않아야 한다.
  • N번 집의 색은 N-1번, 1번 집의 색과 같지 않아야 한다.
  • i(2 ≤ i ≤ N-1)번 집의 색은 i-1, i+1번 집의 색과 같지 않아야 한다.

 

빨간색으로 표시한 부분이 이전 문제에서 추가된 조건 부분이다

 

→ 바로 앞집이랑만 다른 색이면 된다
1번집 색은 마지막집 색이랑 달라야 한다

 

추가로 고려해야 하는 점도 빨간색으로 표시해보았다

마지막 집의 색만 1번집과 겹치지 않도록 고려하면 되는 것이다

 

조건 자체는 쉽지만, 코드로 구현하는 과정이 쉽지만은 않다(첫 번째 집의 색깔을 저장할 방법이 떠오르지 않았다)

https://kyu9341.github.io/algorithm/2020/02/19/algorithm17404/

그래서 이 블로그를 참고했다

핵심 방법은

1. 첫번째 집의 색깔을 고르고, 다른 색깔은 최대값으로 설정하여 선택되지 않도록 막는다

2. 기존의 RGB 거리 문제와 같은 코드를 적는다

3. 마지막 집의 색깔이 첫번쨰 집의 색깔과 겹치지 않도록 한다

 

 

 


정답 인정 코드


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import java.io.*;
import java.util.*;
 
public class Main {
 
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = null;
        
        int n = Integer.parseInt(br.readLine());
        int[][] rgb = new int[n][3];
        int[][] dp = new int[n][3];        
        
        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());
            }
        }
        // 디버깅 System.out.println(Arrays.deepToString(rgb));
        
        int min = Integer.MAX_VALUE;
        for(int first = 0; first < 3; first++) {
        // 0: 빨강, 1: 초록, 2: 파랑
        // 첫번째 선택된 색에 따라 나누기
            
            for(int i = 0; i < 3; i++) {
                // 내가 선택하려는 색이 아니면
                if(i != first) {
                    // 첫번째 집으로 선택되지 않도록 최고값으로 설정
                    dp[0][i] = 1_001;
                }else {
                    // 내가 선택하려는 색의 값은 문제에 주어진 값 그대로
                    dp[0][i] = rgb[0][i];
                }
            }
            
            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];
            }
            
            for(int i = 0; i < 3; i++) {
                if(i != first) {    // 마지막집의 색깔이 첫번째 색깔과 겹치지 않도록 조건 설정
                    min = Math.min(min, dp[n-1][i]);
                }
            }
        }
        
        System.out.println(min);
        
    }
 
}
 
cs

 

주석에 설명을 자세히 적었다

 

 

 


과정만 안다면 코드 구현은 꽤 잘한다고 생각했어서 조금 당황했다

열심히 배워야겠다

 

반응형