프로그래머스/lv2

프로그래머스 : 연습문제 > 땅따먹기(lv2) c++

TIN9 2023. 5. 2.
반응형

프로그래머스 링크

https://school.programmers.co.kr/learn/courses/30/lessons/12913

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제 설명

땅따먹기 게임을 하려고 합니다. 땅따먹기 게임의 땅(land)은 총 N행 4열로 이루어져 있고, 모든 칸에는 점수가 쓰여 있습니다. 1행부터 땅을 밟으며 한 행씩 내려올 때, 각 행의 4칸 중 한 칸만 밟으면서 내려와야 합니다. 단, 땅따먹기 게임에는 한 행씩 내려올 때, 같은 열을 연속해서 밟을 수 없는 특수 규칙이 있습니다.

예를 들면,

| 1 | 2 | 3 | 5 |

| 5 | 6 | 7 | 8 |

| 4 | 3 | 2 | 1 |

로 땅이 주어졌다면, 1행에서 네번째 칸 (5)를 밟았으면, 2행의 네번째 칸 (8)은 밟을 수 없습니다.

마지막 행까지 모두 내려왔을 때, 얻을 수 있는 점수의 최대값을 return하는 solution 함수를 완성해 주세요. 위 예의 경우, 1행의 네번째 칸 (5), 2행의 세번째 칸 (7), 3행의 첫번째 칸 (4) 땅을 밟아 16점이 최고점이 되므로 16을 return 하면 됩니다.

제한사항
  • 행의 개수 N : 100,000 이하의 자연수
  • 열의 개수는 4개이고, 땅(land)은 2차원 배열로 주어집니다.
  • 점수 : 100 이하의 자연수
입출력 예 | land | answer
[[1,2,3,5],[5,6,7,8],[4,3,2,1]] 16

나의 코드 (정답 X)

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int answer;

int solution(vector<vector<int> > land)
{
    int Index = -1;
    vector<vector<pair<int, int>>> vec;
    
    size_t Size = land.size();
    
    for(size_t i = 0; i < Size; ++i)
    {
        size_t NumbSize = land[i].size();
        
        vector<pair<int, int>> vecPair;
        vecPair.reserve(NumbSize);
        
        for(size_t j = 0; j < NumbSize; ++j)
        {
            vecPair.push_back(make_pair(land[i][j], j));
        }
        
        sort(vecPair.begin(), vecPair.end(), greater<pair<int, int>>());
        
        if(Index != vecPair[0].second)
        {
            Index = vecPair[0].second;
            answer += vecPair[0].first;
        }
        else
        {
            answer += vecPair[1].first;
            Index = vecPair[1].second;
        }
        
        vec.push_back(vecPair);
    }
    
    
    
    return answer;
}

결과

필자의 경우 테스트 1번 케이스는 합격을 했는데 나머지 테스트 케이스는 전부 실패했다.

알고보니 필자는 탐욕법을 베이스로 한 풀이를 했는데 정답의 경우 동적프로그래밍을 활용해야 했다.

 

[[1, 1, 3, 1], [2, 3, 2, 2], [1, 4, 1, 1]] 라는 배열이 있을때

 

나의 코드 풀이방식의 결과 : 3 + 3 + 1 = 7
실제 최댓값 : 3 + 2 + 4 = 9 이 되는것을 볼 수 있다...

 

dp 방식의 풀이는 구글링 참고

참고한 코드

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int solution(vector<vector<int> > land)
{
    int answer = 0;
    for (int i = 0; i < land.size() - 1; i++) 
    {
        int NextIndex = i + 1;
        land[NextIndex][0] += max(land[i][1], max(land[i][2], land[i][3]));
        land[NextIndex][1] += max(land[i][0], max(land[i][2], land[i][3]));
        land[NextIndex][2] += max(land[i][0], max(land[i][1], land[i][3]));
        land[NextIndex][3] += max(land[i][0], max(land[i][1], land[i][2]));
    }
    answer = max(land[land.size() - 1][0], max(land[land.size() - 1][1], max(land[land.size() - 1][2], land[land.size() - 1][3])));
    return answer;
}

코드 풀이

land[NextIndex][0] += max(land[i][1], max(land[i][2], land[i][3]));

의 부분을 살펴보면

land의 NextIndex 열에 0번행의 값에 이전 열의 1, 2, 3행의 값중 최대값을 구해 더해준다.

여기서 1, 2, 3행의 값 중 최대값을 구하는 이유는 조건에 다음 열 넘어갈때

같은 행을 동일하게 뽑으면 안된다고 되어있기 때문이다.

위와 같은 방식을 3번 행까지 반복을 한 뒤 마지막 열의 모든행중 최대값을 구해 정답을 갱신해준다.

 

정확성

반응형

댓글