백준 17404

dlwogns·2022년 11월 5일
0

백준

목록 보기
19/34

문제

RGB거리에는 집이 N개 있다. 거리는 선분으로 나타낼 수 있고, 1번 집부터 N번 집이 순서대로 있다.

집은 빨강, 초록, 파랑 중 하나의 색으로 칠해야 한다. 각각의 집을 빨강, 초록, 파랑으로 칠하는 비용이 주어졌을 때, 아래 규칙을 만족하면서 모든 집을 칠하는 비용의 최솟값을 구해보자.

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

입력

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

출력

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

풀이

기본 DP형의 문제인 RGB거리의 변형이다. (스티커 와 유사, Atcoder Educational Dp contest에도 유사문제 있음)

다만 첫번째 행과 마지막 행이 연관이 있어 배열이 사이클을 돈다는 것을 알 수 있다.

본인은 굉장히 더럽게 풀었는데, 배열을 세개를 두어 i번째 색을 칠하는 마지막 행의 결과가 첫번째 행에서 i번째 색을 칠하는 결과를 포함하지 않게 하기 위해 i번째 배열의 첫번째 행의 i번째 색의 값을 이 문제에서의 최댓값인 1000 * 1000 + 1로 바꾸어 포함이 안되게 해주었다.

점화식은 행렬의 N, i번째 요소가 max((N-1, (i+1)%3), (N-1, (i+2)%3)) + N번째 행의 i번째 색깔을 칠하는 값 이다.

정답 코드

#include <iostream>
#include <algorithm>
using namespace std;
int N, board[1001][3], dp1[1001][3], dp2[1001][3], dp3[1001][3];
int main(){
    cin>>N;
    for(int i=1; i<=N; i++)
        for(int j=0; j<3; j++)
            cin>>board[i][j];
    dp1[1][0] = 1000001;
    dp1[1][1] = board[1][1];
    dp1[1][2] = board[1][2];
    dp2[1][1] = 1000001;
    dp2[1][0] = board[1][0];
    dp2[1][2] = board[1][2];
    dp3[1][2] = 1000001;
    dp3[1][1] = board[1][1];
    dp3[1][0] = board[1][0];
    for(int i=2; i<=N; i++){
        for(int j=0; j<3; j++){
            dp1[i][j] = min(dp1[i-1][(j+1)%3],dp1[i-1][(j+2)%3]) + board[i][j];
        }
    }
    for(int i=2; i<=N; i++){
        for(int j=0; j<3; j++){
            dp2[i][j] = min(dp2[i-1][(j+1)%3],dp2[i-1][(j+2)%3]) + board[i][j];
        }
    }
    for(int i=2; i<=N; i++){
        for(int j=0; j<3; j++){
            dp3[i][j] = min(dp3[i-1][(j+1)%3],dp3[i-1][(j+2)%3]) + board[i][j];
        }
    }
    cout<<min(dp1[N][0],min(dp2[N][1],dp3[N][2]));
}
profile
난 커서 개발자가 될래요

0개의 댓글