본문 바로가기

프로그래밍/PS

[C++] 백준 17404번: RGB거리 2

반응형

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

 

17404번: RGB거리 2

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

www.acmicpc.net

전형적인 DP 유형의 문제다. 하지만 거기서 조금만 더 생각해야 했던 문제. 첫 번째 집을 어떤 색으로 칠했냐에 따라 마지막 집의 색이 제한된다. 그래서 나는 첫 집을 빨간색, 초록색, 파란색으로 칠했을 경우로 나누어 계산했다. 매 번 배열을 INF로 초기화 한 뒤, 앞 단계에서의 최솟값을 찾는 방식이다.

#include <bits/stdc++.h>

using namespace std;

#define TC(T) int T; cin >> T; while(T--)
#define FAST_IO cin.tie(NULL); ios::sync_with_stdio(false);
#define FOR(i, N) for(int i = 0; i < N; ++i)
#define ERR 1e-13
#define EL "\n"
#define VI vector<int>
#define VVI vector<VI>
#define VVVI vector<VVI>
#define VP vector<pair<int, int>>
#define VVP vector<VP>
#define VB vector<bool>


int main() {
#ifdef DEBUG
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#endif
	FAST_IO;

	constexpr int R = 0, G = 1, B = 2;
	constexpr int INF = numeric_limits<int>::max();
	int N;
	cin >> N;

	VVI cost(N, VI(3));
	FOR(i, N)
		cin >> cost[i][R] >> cost[i][G] >> cost[i][B];

	int minCost = INF;
	FOR(C, 3) {
		VVI paint(N, VI(3, INF));
		paint[0][C] = cost[0][C];
		for (int i = 1; i < N; ++i) {
			int minPrev = INF;
			if ((minPrev = min(paint[i - 1][G], paint[i - 1][B])) < INF)
				paint[i][R] = minPrev + cost[i][R];
			if ((minPrev = min(paint[i - 1][R], paint[i - 1][B])) < INF)
				paint[i][G] = minPrev + cost[i][G];
			if ((minPrev = min(paint[i - 1][R], paint[i - 1][G])) < INF)
				paint[i][B] = minPrev + cost[i][B];
		}
		switch (C) {
		case R:
			minCost = min(minCost, min(paint[N - 1][G], paint[N - 1][B]));
			break;
		case G:
			minCost = min(minCost, min(paint[N - 1][R], paint[N - 1][B]));
			break;
		case B:
			minCost = min(minCost, min(paint[N - 1][R], paint[N - 1][G]));
			break;
		}
	}

	cout << minCost << EL;

	return 0;
}

반응형