문제
리뷰
최소값을 구하는 문제이므로 DP로 문제를 풀었다. (최소, 최대, 경우의 수는 DP로 푼다)
이 문제는 '직전 값'과는 다른 색깔을 선택해야 한다는 것이 핵심이었다.
그래서 직전에 어떤 색을 칠했는지를 고려해서 현재 무슨 색을 선택할지 결정한다.
ex) 1을 칠했다면, 다음에는 2또는 3 중에서만 최소값을 골라야 한다.
역으로 생각하면, 현재 2를 칠한다면, 직전에는 1또는 3을 택했어야 한다.
배열 A에는 1행에서 R,G,B 값을 저장했다. 인덱스는 1,2,3 을 썼다.
배열 D에는 1행에서 마지막으로 R, G, B 값을 칠했을 경우의 최소값을 저장한다.
배열 A, D 둘다 0행이 아니라 1행부터 시작한다.
배열 D의 초기화는 배열 A의 1행의 값들로 초기화된다.
왜냐하면, 1번째 집에서 마지막으로 R값을 칠한 것의 최소값이 1번째 집의 R값이기 때문이다.
// D 배열 인덱스도 1부터 시작.
D[1][1] = A[1][1]; // R을 마지막으로 칠한 경우.
D[1][2] = A[1][2]; // G를 마지막으로 칠한 경우.
D[1][3] = A[1][3]; // B를 마지막으로 칠한 경우.
예를 들어, D[ 2 ] [ 2 ] 값을 구해보자.
D[ 2 ] [ 2 ] 는 2 번째 집을 G로 칠한 경우(2번째 색을 선택)의 최소값이다.
이것은 D[1] [1] 과 D[1] [3] 을 비교한 값에 A[2] [2] 를 더해서 구해진다.
1번째 집을 R값으로 칠한 경우의 최소값과 1번째 집을 B값으로 칠한 경우의 최소값 둘을 비교해서 최소값을 고른다. 그리고 현재 행 (2번째 집) A[2] [2 ] 값을 더한다.
따라서 점화식을 옮긴 코드는 아래와 같다.
for(i = 2; i <= house; i++){ // 인덱스 2부터 시작
D[i][1] = min(D[i-1][2], D[i-1][3]) + A[i][1]; // 현재 1를 택했다면, 직전에 2또는 3을 선택.
D[i][2] = min(D[i-1][1], D[i-1][3]) + A[i][2]; // 현재 2를 택했다면, 직전에 1또는 3을 선택.
D[i][3] = min(D[i-1][1], D[i-1][2]) + A[i][3]; // 현재 3을 택했다면, 직전에 1또는 2을 선택.
}
코드
#include <stdio.h>
#include <algorithm>
using namespace std;
int A[1001][4]; // 3색 값 입력 받음
int D[1001][4];
int main(void){
int house, fir, se, th = 0;
int i = 0;
scanf("%d", &house);
for(i = 1; i <= house; i++){
scanf("%d %d %d", &fir, &se, &th);
A[i][1] = fir;
A[i][2] = se;
A[i][3] = th;
} // 입력받기 끝
// D 배열 인덱스도 1부터 시작.
D[1][1] = A[1][1]; // 1을 마지막으로 칠한 경우.
D[1][2] = A[1][2]; // 2를 마지막으로 칠한 경우.
D[1][3] = A[1][3];
for(i = 2; i <= house; i++){ // 인덱스 2부터 시작
D[i][1] = min(D[i-1][2], D[i-1][3]) + A[i][1]; // 현재 1를 택했다면, 직전에 2또는 3을 선택.
D[i][2] = min(D[i-1][1], D[i-1][3]) + A[i][2]; // 현재 2를 택했다면, 직전에 1또는 3을 선택.
D[i][3] = min(D[i-1][1], D[i-1][2]) + A[i][3]; // 현재 3을 택했다면, 직전에 1또는 2을 선택.
}
// 마지막 줄에는, 각각 마지막에 1또는 2또는 3을 칠한 경우의 최소값들이 들어있다.
printf("%d", min( min(D[house][1], D[house][2]), D[house][3] ));
return 0;
}
728x90
'알고리즘 > 백준' 카테고리의 다른 글
연속합2 백준 13398 (0) | 2020.08.22 |
---|---|
연속합 백준 1912번 (0) | 2020.08.19 |
동물원 백준 1309 (0) | 2020.08.18 |
1,2,3 더하기3 백준 15988 (0) | 2020.08.17 |
가장 긴 증가하는 부분 수열 백준 11053 (0) | 2020.08.17 |