광물 캐기(그리디)

2023. 8. 4. 09:10C++/알고리즘

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

 

프로그래머스

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

programmers.co.kr

 

어떤 기준으로 그리디 하게 접근해야 하는지 고민해 봐야 하는 문제다.

 

모든 광물에 대해서 다이아, 철, 돌 곡괭이 순서로 피로도 소모가 적다. → 그리디

다이아, 철, 돌 곡괭이중 모든 광물에 대해 다른 값을 갖고있는 것은 돌 곡괭이 뿐이다. → 기준

 

즉, 각 광물에 대해서 돌 곡괭이로 캤을때의 피로도를 구하고

돌 곡괭이로 캤을때 가장 피로도가 높은 광물들 먼저 다이아->철->돌 곡괭이 순서로 사용해서 그리디하게 접근해야한다.

 

이런 과정에서 광물을 5개 단위로 캐야한다는 점, 곡괭이를 전부 사용한 이후의 광물에 대해선 캘 수 없다는 점에 유의하여야 한다.

 

#include <string>
#include <vector>
#include <algorithm>
using namespace std;

bool comp(vector<int>& vec1, vector<int>& vec2)
{
    return vec1[2] > vec2[2];
}

int solution(vector<int> picks, vector<string> minerals)
{
    vector<vector<int>> mine;
    int mine_length = minerals.size();
    int dia = 0;
    int iro = 0;
    int sto = 0;
    // 5개 단위로 각 곡괭이마다 피로도량으로 정리해준다
    for (int i = 0; i < mine_length; i++)
    {
        string next = minerals[i];
        if (next == "diamond")
        {
            dia += 1;
            iro += 5;
            sto += 25;
        }
        else if (next == "iron")
        {
            dia += 1;
            iro += 1;
            sto += 5;
        }
        else
        {
            dia += 1;
            iro += 1;
            sto += 1;
        }
        if ((i + 1) % 5 == 0 || i == mine_length - 1)
        {
            mine.push_back({ dia, iro, sto });
            dia = iro = sto = 0;
        }
    }
    // 현재 곡괭이들로 캘 수 있는 구간만 남겨둔다
    int total_pickage = picks[0] + picks[1] + picks[2];
    while (mine.size() > total_pickage) mine.pop_back();
    // 돌 곡괭이로 캤을때 피로도를 기준으로 내림차순 해준다
    sort(mine.begin(), mine.end(), comp);
    // 돌 곡괭이로 캤을때 가장 많은 피로도를 소모하는 광물들부터 다이아->철->돌 순서로 사용한다
    int answer = 0;
    for (vector<int>& vec : mine)
    {
        if (0 < picks[0]--)
        {
            answer += vec[0];
        }
        else if (0 < picks[1]--)
        {
            answer += vec[1];
        }
        else if (0 < picks[2]--)
        {
            answer += vec[2];
        }
        else break;
    }
    return answer;
}

'C++ > 알고리즘' 카테고리의 다른 글

타일링(DP)  (0) 2023.08.16
수식 최대화(순열, 완전 탐색)  (0) 2023.08.08
의상(해시, 조합 접근법)  (0) 2023.07.21
Quick Sort  (0) 2023.05.22
레이스(이분 탐색, 그리디)  (0) 2023.05.17