공부/백준

1149번: RGB거리(백준 C++)

상연 2020. 11. 17. 16:23

1149번: RGB거리 링크

코드

#include <iostream>
using namespace std;

// RGB 거리
int rgb[1000][3];

// 집을 색칠하는데 드는 비용 입력 받기
void init(int n){
    for(int i=0; i<n; i++){
        cin >> rgb[i][0] >> rgb[i][1] >> rgb[i][2];
    }
}

void solve(int n){
    for(int i=1; i<n; i++){
        for(int j=0; j<3; j++){
            if(rgb[i-1][(j+1) % 3] < rgb[i-1][(j+2) % 3]){
                rgb[i][j] += rgb[i-1][(j+1) % 3];
            }
            else{
                rgb[i][j] += rgb[i-1][(j+2) % 3];
            }
        }
    }
    int min = 1000001;
    for(int k=0; k<3; k++){
        if( rgb[n-1][k] < min ) min = rgb[n-1][k];
    }
    cout << min;
}
int main() {
    int n;
    cin >> n;
    init(n);
    solve(n);
    return 0;
}

풀이 및 사견

문제

선형으로 집이 N개 놓여져 있다고 생각하자.
각 집은 R, G, B 3개의 색 중 하나다. 단, 이전 집에 칠한 색으로는 할 수 없다.
색마다 칠하는 비용이 다르다고 하면, 칠하는데 드는 가장 최소의 비용은?


점화식

생각을 단순하게 해야한다.
N번째 집을 칠할때 최소의 비용이 되려면?

(N -1)번째 집까지 칠하는데 드는 최소의 비용 + N번째 집칠하는 최소의 비용

단 R, G, B 선택에 따른 최소값이 각 각 다르므로 3가지 색에 대한 최소값을 모두 구해야 한다

  • 전체 색에서의 최소값만 구하게 된다면 어떤 문제점이?

위의 경우를 보자

  • N = 1 최소값

    1, 색상 R

  • N = 2 최소값

    N = 1 까지의 최소값은 1이고, 색상은 R
    N = 2에서 색상이 R이 아닌 것 중 최소값 1, 색상 G
    N = 2까지의 최소값 1 + 1 = 2

  • N = 3 최소값 :

    N = 2 까지의 최소값은 2이고, 색상은 G
    N = 3에서 색상이 G가 아닌 것 중 최소값, 888 색상 B
    N = 3까지의 최소값 2 + 888 = 890

뭔가 이상하다.

그림만 보고 곰곰히 생각해보면 최소비용은
R - > B - > G 순으로 칠해져서
1 + 5 + 1 이 되어야 하지만
N = 2 일때 그 순간의 최소값이 2라는 함정에 빠지게 된 것이다.

따라서 점화식은 R, G, B 에 따른 3개를 운용해야 한다.

변수

int rgb[1000][3];

집을 칠하는 데 필요한 비용을 담는 배열을 선언한다.
rgb[집의 개수][색의 개수]
이후, Input 따라 배열을 채워준다.

풀이

void solve(int n){
    for(int i=1; i<n; i++){
        for(int j=0; j<3; j++){
            if(rgb[i-1][(j+1) % 3] < rgb[i-1][(j+2) % 3]){
                rgb[i][j] += rgb[i-1][(j+1) % 3];
            }
            else{
                rgb[i][j] += rgb[i-1][(j+2) % 3];
            }
        }
    }
    int min = 1000001;
    for(int k=0; k<3; k++){
        if( rgb[n-1][k] < min ) min = rgb[n-1][k];
    }
    cout << min;
}

이중 반복문을 써서 각 N에 대한 각 색상별 최소값을 구하게 된다.
i는 N을 나타내는 변수
j는 색상을 나타내는 변수 0:R 1:G 2:B

j= 0이면 이전 N의 j = 1 과 j = 2를 비교해서 작은값과 더해줘야한다.
j = 1이면 이전 N의 j = 0 과 j = 2를 비교해서 작은값과 더해줘야한다.
j = 2이면 이전 N의 j = 0 과 j = 1를 비교해서 작은값과 더해줘야한다.

이는

if(rgb[i-1][(j+1) % 3] < rgb[i-1][(j+2) % 3]){
                rgb[i][j] += rgb[i-1][(j+1) % 3];
            }
            else{
                rgb[i][j] += rgb[i-1][(j+2) % 3];
            }

이렇게 할 수 있다.

이렇게 N = 3까지 진행하게 되면

N = 3 에서 RGB는 (96, 172, 185)

이 셋 중 최소값을 구하게 되면 96으로 96이 정답이 된다.

'공부 > 백준' 카테고리의 다른 글

2579번: 계단 오르기(백준 C++)  (0) 2020.11.20
1932번: 정수 삼각형(백준 C++)  (0) 2020.11.18
9461번: 파도반 수열(백준 C++)  (0) 2020.11.16
1904번: 01타일(백준 C++)  (0) 2020.11.15
1003번: 피보나치 함수(백준 C++)  (0) 2020.11.14