BOJ

[백준] 1149번 RGB거리 - C++

DP, 다이나믹 프로그래밍

Posted by dongjune on December 17, 2020

문제

1149번 RGB거리

풀이

DP를 사용해서 풀 수 있습니다.
메모이제이션을 수행 할 2차원 배열을 만들어줍니다. 3가지 색이 있기 때문에 배열 크기는 N행 3열이 됩니다.
이 문제에서 중요한 점은 앞 뒤로 색이 연속되면 안됩니다. 그렇기 때문에 다음의 코드와 같이 현재 color가 rgb중 r이라고 하면 앞 집은 g와 b중 하나가 되어야 합니다.

1
2
3
// r:0, g:1, b:2
// 현재집 i를 0(빨강)으로 칠하므로 앞집 i-1은 1(초록)과 2(파랑)로 칠합니다. 
cache[i][0] = min(cache[i-1][1], cache[i-1][2]) + cost[i][0];

반복문을 사용한 코드와 재귀함수를 사용한 코드 두 가지를 작성해봤습니다.

반복문 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <algorithm>
#include <vector>
#include <iostream>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int n;
    cin >> n;

    // 집의 가격을 저장하는 vector
    vector<vector<int>> cost(n, vector<int>(3));
    for (int i = 0; i < n; i++)
        for (int j = 0; j < 3; j++)
            cin >> cost[i][j];
    
    // 최대가격을 저장하는 벡터
    vector<vector<int>> cache(n, vector<int>(3, 0));

    // 가장 앞집의 최대 가격은 자신의 가격
    for (int i = 0; i < 3; i++)
        cache[0][i] = cost[0][i];
    // 메모이제이션
    for (int i = 1; i < n; i++)
    {
        cache[i][0] = min(cache[i - 1][1], cache[i - 1][2]) + cost[i][0];
        cache[i][1] = min(cache[i - 1][0], cache[i - 1][2]) + cost[i][1];
        cache[i][2] = min(cache[i - 1][1], cache[i - 1][0]) + cost[i][2];
    }
    cout << min({cache[n - 1][0], cache[n - 1][1], cache[n - 1][2]});
    return 0;
}

재귀함수 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <vector>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

int n;
int colors[1001][3];
int cache[1001][3];

int getCost(int house, int color)
{
    // 기저사례
    if (house == 0)
        return colors[house][color];
    // 값을 구한 적 있으면 바로 return
    if (cache[house][color] != -1)
        return cache[house][color];
    if (color == 0)
        return cache[house][0] = colors[house][0] + min(getCost(house - 1, 1), getCost(house - 1, 2));
    else if (color == 1)
        return cache[house][1] = colors[house][1] + min(getCost(house - 1, 0), getCost(house - 1, 2));
    else
        return cache[house][2] = colors[house][2] + min(getCost(house - 1, 1), getCost(house - 1, 0));
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> colors[i][0] >> colors[i][1] >> colors[i][2];
    memset(cache, -1, sizeof(cache));
    int cand0 = getCost(n, 0); 
    int cand1 = getCost(n, 1);
    int cand2 = getCost(n, 2);
    cout << min(min(cand0, cand1), cand2);

    return 0;
}