백준 문제풀이/Dynamic Programming

[DP] BOJ 1149 번 문제 풀이

준코딩 2019. 5. 6. 16:00

문제 분석 

 

문제는 RGB 거리에 R,G,B 의 색으로 집을 칠하는 최소비용을 

구하는 것이다. 

이때, 이웃하는 집의 색은 달라야 한다.

 

예를 들어

 

G 의 인덱스가 i 라고 할 때

i + 1 과 i - 1 이 이웃하는 집이다.

 

우선 최소비용과 색을 포함할 수 있는 배열을 선언하자.

 

d[i][0] = i 번째 집까지 칠할 때 최소비용 단, i 번째 집은 빨간색

d[i][1] = i 번째 집까지 칠할 때 최소비용 단, i 번째 집은 초록색

d[i][2] = i 번째 집까지 칠할 때 최소비용 단, i 번째 집은 파란색

 

이제 배열이 선언됐으니 점화식을 끌어내 보자.

우선 경우의 수가 하나밖에 없는 초깃값들을 초기화 하자.

 

d[0][0] = s[0][0] , d[0][1] = s[0][1] , d[0][2] = s[0][2]

 

두 번째 집은 무조건 이전 집의 색을 사용할 수 없다.

따라서 

 

d[1][0] = min( d[0][1] , d[0][2] ) + s[1][0]

 

이처럼 현재 집의 색을 제외한 

두 가지 색 중 저렴한 것을 택한다.

 

역시 초록과 파란색인 경우도 따져봐야 한다.

 

결과적으로 점화식은 

 

d[i][0] = min( d[i-1][1] , d[i-1][2] ) + s[i][0]

 

될 것이고 결괏값은

 

cout << min( min( d[n-1][0], d[n-1][1] ), d[n-1][2] )

 

min은 두 개의 인수를 받는 함수이므로 

두 번 사용해서 3개를 비교한다.

 

코드

#include "bits/stdc++.h"

using namespace std;

int d[1000][3];
int n;
int s[1000][3];
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> s[i][0] >> s[i][1] >> s[i][2];
	}

	d[0][0] = s[0][0];
	d[0][1] = s[0][1];
	d[0][2] = s[0][2];
	for (int i = 1; i <= n; i++)
	{
		d[i][0] = min(d[i - 1][1], d[i - 1][2])+ s[i][0];
		d[i][1] = min(d[i - 1][0], d[i - 1][2])+ s[i][1];
		d[i][2] = min(d[i - 1][1], d[i - 1][0])+ s[i][2];
	}

	cout << min(min(d[n - 1][0], d[n - 1][1]), d[n - 1][2]);

}