문제 설명
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보다 작거나 같은 자연수이다.
출력
첫째 줄에 모든 집을 칠하는 비용의 최솟값을 출력한다.
문제해결
다이나믹 프로그래밍을 이용해서 문제를 풀 수 있다.
1. 테이블 설정
D[i][0] = i번째 집을 빨간색으로 색칠 했을 때 누적 최소비용
D[i][1] = i번째 집을 초록색으로 색칠 했을 때 누적 최소비용
D[i][2] = i번째 집을 파란색으로 색칠 했을 때 누적 최소비용
2. 초기값
D[1][0] = R[1]
D[1][1] = G[1]
D[1][2] = B[1]
3. 점화식 세우기
D[i][0] = min (D[i-1][1],D[i-1][2])+R[i];
D[i][1] = min (D[i-1][0] ,D[i-1][2]) + G[i];
D[i][2] = min (D[i-1][1] , D[i-1][0])+B[i];
따라서 i=2 부터 for문을 돌려 각각 D[i][0] , D[i][1] ,D[i][2] 를 구하고
최종적으로 *(min_element(D[N], D[N+3])) 를 통해 누적 최소비용을 구할 수 있다.
코드
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int D[1000][1000];
int R[1000];
int G[1000];
int B[1000];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int N,cost;
cin >> N;
for (int i = 1; i <= N; i++) {
cin >> R[i] >> G[i] >> B[i];
}
D[1][0] = R[1];
D[1][1] = G[1];
D[1][2] = B[1];
for (int i = 2; i <= N; i++) {
D[i][0] = min(D[i - 1][1], D[i - 1][2]) + R[i];
D[i][1] = min(D[i - 1][0], D[i - 1][2]) + G[i];
D[i][2] = min(D[i - 1][0] , D[i - 1][1]) + B[i];
}
cout << *(min_element(D[N], D[N] + 3));
}
'알고리즘 > 문제풀이 (C++,Kotlin)' 카테고리의 다른 글
[BOJ/C++] 1931번 회의실 배정 : 그리디 (0) | 2023.01.22 |
---|---|
[BOJ/C++] 11726번 2xn 타일링 : DP(다이나믹 프로그래밍) (0) | 2023.01.20 |
[BOJ/C++,Kotlin] 2579번 계단오르기 : DP(다이나믹 프로그래밍) (0) | 2023.01.18 |
[BOJ/C++] 9095번 1,2,3 더하기 : BFS or DP(다이나믹 프로그래밍) (0) | 2023.01.17 |
[BOJ/C++] 1463번 1로 만들기 : BFS or 다이나믹 프로그래밍(DP) (0) | 2023.01.16 |