[BOJ] 1149_RGB거리

ProblemSolving / / 2021. 1. 27. 00:52

RGB거리

문제 링크: https://www.acmicpc.net/problem/1149

 

1149번: RGB거리

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

www.acmicpc.net

이 문제는 Dynamic Programming 문제이다.
하나의 선택을 했을 경우 다음의 선택에서는 두 개의 선택지로 나뉘어진다.
우리는 가장 최솟값을 구해야한다.
그 두 개의 선택지 중 더 작은 값을 고르면 된다.

 

하지만 반대로 내가 하나의 선택을 했다면, 이전에 걸어왔던 선택지에서 현재 내가 선택한 색상을 제외한 나머지를 선택할 수 있다.

 

만일 현재 내가 r를 선택했다면, 이전에 g 또는 b를 골랐던 선택지를 가져온다.
똑같이 현재 내가 g를 선택했다면, 이전에 r 또는 b를 골랐던 선택지를 가져온다.
b도 동일하게 ,r 또는 g를 골랐던 선택지를 가져온다.

 

이제 두 개의 선택지 중 더 작은 값들을 가져온다.
그렇게 한다면, 현재의 선택에서 가장 작은 값들을 유추할 수 있다.

 

마지막까지 간 후 마지막의 선택에서 가장 작은 선택지를 고르면 된다.

 

  • 정답코드

      #include<iostream>
      #include<vector>
      #include<algorithm>
      using namespace std;
    
      int main() {
          int n;
          cin >> n;
          int dp[3] = { 0, };
    
          while (n--) {
              int r, g, b;
              cin >> r >> g >> b;
              int temp[3] = { 0, };
              temp[0] = r + min(dp[1], dp[2]); //이전에 r를 제외한 g 또는 b를 선택
              temp[1] = g + min(dp[0], dp[2]);//이전에 g를 제외한 r 또는 b를 선택
              temp[2] = b + min(dp[0], dp[1]);//이전에 b를 제외한 r 또는 g를 선택
              dp[0] = temp[0]; //이번에 r 선택
              dp[1] = temp[1]; //이번에 g 선택
              dp[2] = temp[2]; //이번에 b 선택
          }
    
          cout << min(dp[0] , min(dp[1], dp[2])) << endl;
          return 0;
      }

 

ps. 원래 이 문제를 혼자서 해결하지 못하였다.
내 첫 걸음은 rgb 각각의 색상에 플래그를 세워준 것이다.
이전에 빨간색을 골랐다면 이전에 고른 플래그와 비교하여 빨간색 이외의 색상을 고르게 한다.
초롱 파랑도 동일하다.
해당 색상 이외의 값 중 더 작은 값들을 고르면 최솟값이라 생각을 했다.
하지만 이 경우 현재의 최선의 선택만 할 뿐 전체 흐름에서 최고의 선택이 되지 않는다.
내 코드는 이 부분에서 틀린 답이 나왔음을 이해하고 처음부터 다시 시작했다.

  • 이전코드

      #include<iostream>
      #include<vector>
      #include<algorithm>
      using namespace std;
    
      class RGB {
      public:
          int rgb[3];
          //int R;
          //int G;
          //int B;
          int flag[3];
          RGB(int r, int g, int b) {
              /*R(r),G(g),B(b){}*/
              rgb[0] = r;
              rgb[1] = g;
              rgb[2] = b;
              if (r < g) {
                  if (r < b) {// r<b,g
                      flag[0] = 0;
                      if (b < g) {
                          //r<b<g
                          flag[1] = 2;
                          flag[2] = 1;
                      }
                      else {
                          //r<g<b
                          flag[1] = 1;
                          flag[2] = 2;
                      }
                  }
                  else {//b < r < g
                      flag[0] = 2;
                      flag[1] = 0;
                      flag[2] = 1;
                  }
              }
              else {
                  if (g < b) {// g<b,r
                      flag[0] = 1;
                      if (b < r) {
                          //g<b<r
                          flag[1] = 2;
                          flag[2] = 0;
                      }
                      else {
                          //g<r<b
                          flag[1] = 0;
                          flag[2] = 2;
                      }
                  }
                  else { // b<g<r
                      flag[0] = 2;
                      flag[1] = 1;
                      flag[2] = 0;
                  }
              }
          }
      };
    
      class card {
      public:
          int a;
          int b;
          int m;
          bool flag;
          card(int a_,int b_) {
              a = a_;
              b = b_; 
              m = min(a, b);
              if (a < b) {
                  flag = true;
                  m = a;
              }
              else {
                  flag = false;
                  m = b;
              }
          }
      };
      int findIdx(vector<RGB*>list) {
          int idx = 0;
          int min = 50000000;
          for (int i = 0; i < list.size(); i++)
              if (min > list[i]->rgb[list[i]->flag[0]]) {
                  min = list[i]->rgb[list[i]->flag[0]];
                  idx = i;
              }
          return idx;
      }
    
    int main() {
        int n;
        cin >> n;
        vector<RGB*> list;
        for (int i = 0; i < n; i++) {
            int arr[3];
            for (int k = 0; k < 3; k++)
                cin >> arr[k];
            list.push_back(new RGB(arr[0], arr[1], arr[2]));
        }
    
        int minIdx =0;
        int count = list[minIdx]->rgb[list[minIdx]->flag[0]];
        int flag = list[minIdx]->flag[0];
        RGB* temp;
        for (int i = minIdx - 1; i >= 0; i--) {
            for (int k = 0; k < 3; k++) {
                temp = list[i];
                if (flag != temp->flag[k]) {
                    count += temp->rgb[temp->flag[k]];
                    flag = temp->flag[k];
                    break;
                }
            }
        }
        flag = list[minIdx]->flag[0];
        for (int i = minIdx+1; i < n; i++) {
            for (int k = 0; k < 3; k++) {
                temp = list[i];
                if (flag != temp->flag[k]) {
                    count += temp->rgb[temp->flag[k]];
                    flag = temp->flag[k];
                    break;
                }
            }
        }
        cout << count << endl;
    
        return 0;
    }

'ProblemSolving' 카테고리의 다른 글

[BOJ] 1927_최소 힙  (0) 2021.01.29
[BOJ] 1106_호텔  (1) 2021.01.28
[BOJ] 19948_음유시인 영재  (0) 2021.01.26
[BOJ] 1931_회의실 배정  (0) 2021.01.25
[BOJ] 1012_유기농 배추  (0) 2021.01.24
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기