[그리디] 구명보트

지은·2023년 5월 22일
0

Algorithm

목록 보기
24/33

그리디(탐욕법) 알고리즘

: 매 선택에서 지금 이 순간 가장 최적인 답을 선택하는 알고리즘 (최적의 해 보장 X)
그리디 알고리즘 (Greedy Algorithm)

문제

무인도에 갇힌 사람들을 구명보트를 이용하여 구출하려고 합니다. 구명보트는 작아서 한 번에 최대 2명씩 밖에 탈 수 없고, 무게 제한도 있습니다.

예를 들어, 사람들의 몸무게가 [70kg, 50kg, 80kg, 50kg]이고 구명보트의 무게 제한이 100kg이라면 2번째 사람과 4번째 사람은 같이 탈 수 있지만 1번째 사람과 3번째 사람의 무게의 합은 150kg이므로 구명보트의 무게 제한을 초과하여 같이 탈 수 없습니다.

구명보트를 최대한 적게 사용하여 모든 사람을 구출하려고 합니다.

사람들의 몸무게를 담은 배열 people과 구명보트의 무게 제한 limit가 매개변수로 주어질 때, 모든 사람을 구출하기 위해 필요한 구명보트 개수의 최솟값을 return 하도록 solution 함수를 작성해주세요.

제한사항

무인도에 갇힌 사람은 1명 이상 50,000명 이하입니다.
각 사람의 몸무게는 40kg 이상 240kg 이하입니다.
구명보트의 무게 제한은 40kg 이상 240kg 이하입니다.
구명보트의 무게 제한은 항상 사람들의 몸무게 중 최댓값보다 크게 주어지므로 사람들을 구출할 수 없는 경우는 없습니다.

입출력 예

peoplelimitreturn
[70, 50, 80, 50]1003
[70, 80, 50]1003

나의 풀이

  1. 먼저 people 배열을 오름차순으로 정렬한다.
  2. people 배열의 길이가 0이 될때까지
    2-1. 먼저 보트에 가장 무거운 사람을 태운다.
    2-2. 그 다음 가장 가벼운 사람을 태울건데, 이때 limit을 초과하면 태우지 않는다.
  3. 위의 과정을 반복한다.
function solution(people, limit) {
    people.sort((a, b) => a - b); // 오름차순 정렬
    let boats = 0;
    
    while(people.length > 0) {
        const heaviest = people.pop(); // 가장 무거운 사람 태움 (people 배열에서 제거)
        const lightest = people[0];
        
        if (lightest + heaviest <= limit) {
            people.shift(); // 가장 가벼운 사람 태움 (people 배열에서 제거)
        }
        boats++;
    }
    
    return boats;
}

다른 사람의 풀이

function solution(people, limit) {
    people.sort((a, b) => a - b);
  
    for (var i = 0, j = people.length - 1; i < j; j--) { // i는 가장 가벼운 사람, j는 가장 무거운 사람
        if(people[i] + people[j] <= limit) i++; // 둘 다 태울 수 있다면 둘 다 태움
    }
  
    return people.length - i;
}

이 문제가 그리디 알고리즘 문제인 이유

  1. 탐욕적 선택
    이 알고리즘은 매번 가장 무거운 사람과 가장 가벼운 사람을 함께 구명보트에 태우려고 한다.
    이렇게 했을 때 보트의 개수를 최소화할 수 있기 때문에, 현재 상황에서 가장 최적의 선택을 하는 것이다.

  2. 최적 부분 구조
    매 선택에서 가장 무거운 사람과 가장 가벼운 사람을 함께 태우며 부분 문제를 최적으로 해결한다.
    이후 남은 사람들에 대해서도 같은 방식으로 최적의 선택을 계속해서 진행한다.

  3. 탐욕적 선택과 최적 부분 구조의 조합
    이 알고리즘은 탐욕적 선택을 계속 반복하면서 문제를 부분 문제로 분할하고, 각 부분 문제에서 탐욕적 선택을 하며 최적해를 찾는다.

➡️ 따라서 탐욕적 선택과 최적 부분 구조의 속성을 이용하여 문제를 해결하는 전형적인 탐욕법 알고리즘이다.

profile
개발 공부 기록 블로그

4개의 댓글

comment-user-thumbnail
2023년 5월 22일

대단하시네요 ㅠㅠ 어렵습니다.. 알고리즘

답글 달기
comment-user-thumbnail
2023년 5월 28일

전에 써놓은 그리디 정의와 같이 보니 좋네요! 잘보고 갑니당

답글 달기
comment-user-thumbnail
2023년 5월 28일

엇 저도 이거 푼 기억이 새록새록...

답글 달기
comment-user-thumbnail
2023년 5월 28일

예전에 풀었던 문제인데 복습하고 갑니다 !!

답글 달기