IT/BOJ 문제정리

백준 1149번: RGB 거리

KimCookieYa 2021. 7. 9. 15:58

https://www.acmicpc.net/problem/1149

 

1149번: RGB거리

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

www.acmicpc.net

 

 

0. 알고리즘 분류

 다이나믹 프로그래밍

 

 

1. 문제

 RGB거리에는 집이 N개 있다. 거리는 선분으로 나타낼 수 있고, 1번 집부터 N번 집이 순서대로 있다. 집은 빨강, 초록, 파랑 중 하나의 색으로 칠해야 한다. 각각의 집을 빨강, 초록, 파랑으로 칠하는 비용이 주어졌을 때, 아래 규칙을 만족하면서 모든 집을 칠하는 비용의 최솟값을 구해보자.

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

 

 

2. 풀이

 분명 알고리즘 분류는 DP인데, 어떻게 써먹어야 풀리는지 생각해내지 못했다.. 그래서 일단 구글링으로 솔루션을 봤다. 생각보다 간단하다. RGB에 대해 dp배열을 3개 만들어서, 각 RGB마다 1번 집부터 i번 집까지의 최솟값을 저장시킨다. 마지막 N번째 집에서는 dp값 3개 중에서 최솟값을 출력하기만 하면 된다. DP도 생각보다 어려우면서 다양한 문제에 적용시킬 수 있다는 걸 깨달았다.

 

 

3. 코드

#include <iostream>

using namespace std;

int min(int x, int y) {
	return (x < y) ? x : y;
}

int main(void) {
	int n;
	cin >> n;
	int cost[n][3];
	int dp[n][3];
	for (int i = 0; i < n; i++) {
		cin >> cost[i][0] >> cost[i][1] >> cost[i][2];
	}
	
	dp[0][0] = cost[0][0]; dp[0][1] = cost[0][1]; dp[0][2] = cost[0][2];
	
	for (int i = 1; i < n; i++) {
		dp[i][0] = cost[i][0] + min(dp[i-1][1], dp[i-1][2]);
		dp[i][1] = cost[i][1] + min(dp[i-1][0], dp[i-1][2]);
		dp[i][2] = cost[i][2] + min(dp[i-1][0], dp[i-1][1]);
	}
	
	int ans = min(min(dp[n-1][0], dp[n-1][1]), dp[n-1][2]);
	cout << ans;
	
	return 0;
}