[dp] 1149. RGB 거리

알고리즘/백준 알고리즘

2020. 2. 14. 20:46

#include <iostream>
using namespace std;

int dp[3][1010];
int A[3][1010];
int ans = 500000;
int min(int x, int y)
{
	if (x < y)return x;
	return y;
}
int main(void)
{
	int n;
	cin >> n;

	for (int i = 1; i <= n; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			cin >> A[j][i];
		}
	}

	//bottom up
	dp[0][0] = dp[1][0] = dp[2][0] = 0;
	dp[0][1] = A[0][1]; dp[1][1] = A[1][1]; dp[2][1] = A[2][1];
	dp[0][2] = min(dp[1][1], dp[2][1]) + A[0][2];
	dp[1][2] = min(dp[0][1], dp[2][1]) + A[1][2];
	dp[2][2] = min(dp[0][1], dp[1][1]) + A[2][2];
	for (int i = 3; i <= n; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			if (j == 0)
				dp[0][i] = min(dp[1][i - 1], dp[2][i - 1]) + A[0][i];
			else if (j == 1)
				dp[1][i] = min(dp[0][i - 1], dp[2][i - 1]) + A[1][i];
			else
				dp[2][i] = min(dp[1][i - 1], dp[0][i - 1]) + A[2][i];
		}
	}

	for (int i = 0; i < 3; i++)
		ans = min(dp[i][n], ans);

	cout << ans << endl;
}

1. 문제 해결 전략

dp 문제는 무조건 Bottom Up 방식으로 해결하기로 결정했다.

(이유는 재귀를 아직 잘 못써먹겠어서..)

 

해당 문제는 정답률이 50%에 육박하는 쉬운 문제에 해당한다.

잡소리는 던져버리구 ..

 

먼저 bottom up으로 전략을 잡았다면 n번째 경우에 대해서 생각을 하자.

n번째 집에 칠하는 색깔은 n-1번째 집의 색깔과 연관이 있다.

같은색으로 칠할 수 없기 때문에 n번째 집에 칠하는 색깔은 n-1번째 집의 색깔과 달라야 한다는 조건

 

그리고, 이 문제는 순서와 색깔 두 가지의 상태가 존재하기 때문에 2중 dp문제라고 할 수 있겠다.

결과로서 최소 비용을 구한다는 점도 잊지말자.

대략의 점화식을 생각 했을 때

dp[m1][n] = min(dp[m2 or m3][n-1],dp[m3 or m2][n-1]) + A[m1][n]
dp[m2][n] = min(dp[m1 or m3][n-1],dp[m3 or m1][n-1]) + A[m2][n]
dp[m3][n] = min(dp[m1 or m2][n-1],dp[m2or  m1][n-1]) + A[m3][n]

// m은 색깔의 경우 , n은 집의 순서다

이런 식으로 생각할 수 있다.

좌변의 식이 n번 째 집이라면 우변의 식은 n-1번 째 집이 선택할 수 있는 경우로서

n번 째 집이 선택하지 않은 색깔중에 하나를 고르고 n-1번 째까지의 비용이 최소가 되는것을 찾는다.

마지막으로 n번째 집의 특정 색일 때 가격을 더해주면 점화식은 끝난다.

 

단, 위의 세가지 점화식은 경우에 따라 각각 나누어 사용해야 하는데

n번 째 집의 색을 결정하는 j돌림 반복문에서 결정하면 되겠다.

 

2. 걸린 시간

대략 15분정도 걸렸다.. 해당 문제를 2중 dp를 쓰냐 단일 dp를 쓰냐에서 시간이 좀 걸렸었던 것 같다.

 

3. 느낀점

이전의 dp문제들을 계속 틀리다가 오랜만에 맞추어서 기분이 굉장히 좋았다 ㅎㅎ!

 

4. 링크

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

'알고리즘 > 백준 알고리즘' 카테고리의 다른 글

[정렬] 11652. 카드  (0) 2020.04.21
[정렬] 10825. 국영수  (0) 2020.02.18
[정렬] 10814. 나이순 정렬  (0) 2020.02.18
[정렬] 11650. 좌표 정렬  (0) 2020.02.18
[정렬] 2571. 수 정렬하기 2  (0) 2020.02.18