코딩테스트/C++

[백준 BOJ] 17404번 - RGB거리 2(C++)

최-코드 2024. 3. 10. 00:00

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

 

17404번: RGB거리 2

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

www.acmicpc.net

DP를 이용하면 쉽게 풀 수 있는 문제이다. 2차원 배열 dp[N][3]로 만들고 for문을 3~N까지 돌면서 해당 level의 집에서 1~3번째의 색으로 칠할 때 해당 번째의 수를 뺀 전의 값 두 개 중에서 min값을 찾아서 더해주면 된다. 즉, dp[i][2]이면 min(dp[i-1][1],dp[i-3])+arr[i][2] 해주면 된다. 이 때 arr[i][2]는 i번째 집을 색칠할 때 드는 비용 중 두 번째의 있는 값이다. 획기적인 생각이 안 떠올라서 첫 번째 집과 두 번째 집의 색을 미리 정해놓고 for문을 돌리는 식으로 만들어서 코드가 길게 되었다.

#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <memory.h>
#include <vector>

#define endl '\n'
#define ll long long
#define pii pair<int, int>
#define max 987654321

using namespace std;

int N;
int arr[1001][4];
int dp[1001][4];

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin >> N;
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= 3; j++)
        {
            cin >> arr[i][j];
        }
    }
    dp[1][1] = arr[1][1];
    dp[2][2] = dp[1][1] + arr[2][2];
    dp[2][3] = dp[1][1] + arr[2][3];
    dp[2][1] = max;
    for (int i = 3; i <= N; i++)
    {
        for (int j = 1; j <= 3; j++)
        {
            if (i == N)
            {
                if (j == 3)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][1], dp[i - 1][2]);
                else if (j == 2)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][1], dp[i - 1][3]);
                else if(j==1)
                    dp[i][j]=max;
            }
            else
            {
                if (j == 3)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][1], dp[i - 1][2]);
                else if (j == 2)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][1], dp[i - 1][3]);
                else if (j == 1)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][2], dp[i - 1][3]);
            }
        }
    }
    int minNum = max;
    for (int i = 1; i <= 3; i++)
    {
        if (minNum > dp[N][i])
            minNum = dp[N][i];
    }
    memset(dp, 0, sizeof(dp));
    dp[1][2] = arr[1][2];
    dp[2][1] = dp[1][2] + arr[2][1];
    dp[2][3] = dp[1][2] + arr[2][3];
    dp[2][2] = max;
    for (int i = 3; i <= N; i++)
    {
        for (int j = 1; j <= 3; j++)
        {
            if (i == N)
            {
                if (j == 3)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][1], dp[i - 1][2]);
                else if (j == 1)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][2], dp[i - 1][3]);
                else if(j==2)
                    dp[i][j]=max;
            }
            else
            {
                if (j == 3)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][1], dp[i - 1][2]);
                else if (j == 2)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][1], dp[i - 1][3]);
                else if (j == 1)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][2], dp[i - 1][3]);
            }
        }
    }
    for (int i = 1; i <= 3; i++)
    {
        if (minNum > dp[N][i])
            minNum = dp[N][i];
    }
    memset(dp, 0, sizeof(dp));
    dp[1][3] = arr[1][3];
    dp[2][2] = dp[1][3] + arr[2][2];
    dp[2][1] = dp[1][3] + arr[2][1];
    dp[2][3] = max;
    for (int i = 3; i <= N; i++)
    {
        for (int j = 1; j <= 3; j++)
        {
            if (i == N)
            {
                if (j == 1)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][2], dp[i - 1][3]);
                else if (j == 2)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][1], dp[i - 1][3]);
                else if(j==3)
                    dp[i][j]=max;
            }
            else
            {
                if (j == 3)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][1], dp[i - 1][2]);
                else if (j == 2)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][1], dp[i - 1][3]);
                else if (j == 1)
                    dp[i][j] = arr[i][j] + min(dp[i - 1][2], dp[i - 1][3]);
            }
        }
    }
    for (int i = 1; i <= 3; i++)
    {
        if (minNum > dp[N][i])
            minNum = dp[N][i];
    }
    cout << minNum;
    return 0;
}