TIL

[코테연습] 구명보트

크라00 2024. 6. 5. 13:41


    오늘 문제는 탐욕법 - 구명보트 문제이다.

    이 문제는 문제를 잘 이해한다면, 어렵지 않은 문제라고 생각한다.

    중요포인트는 구명보트를 최대한 적게 사용해야한다는 점이다.

    단순하게 생각하면 [40,50,50,60,70] // limit : 100 이라는 숫자가 주어졌을때

    가장 몸무게가 작은 사람 40, 50, 을 구출하고
    이후 50 // 60 // 70 을 구출하여 4번 왕복하면 된다.
    하지만 구명보트를 최대한 적게 사용하는 방법은 아니다.

    구명보트를 최대한 적게 사용하는 방법은 40, 60 // 50, 50 // 70 이다.
    즉 몸무게가 가장 적은 사람이 먼저 타고 몸무게가 가장 많은 사람 중에서 같이 탔을 때 limit 에 걸리지 않은 사람이다.
    
    이것을 논리적으로 풀이하면 다음과 같다.


     1. 사람 몸무게 배열 Dqueue 에 담는다.
     2. Deque 을 오름차순으로 정렬한다.
     3. 가장 적은 수를 pick 한다. (first)
     4. 가장 많은 수 (last)에서 limit 보다 작거나 같을때까지 뽑는다.
     5. 버려지는 수만큼 count 한다
     6. 가장 적은 수+가장 많은 수 가 limit 보다 작으면 count 를 한개만 늘린다.
     7. Dqueue 가 empty 일때까지 반복한다.
    
    
    Dequeue 를 이용하였으며, 코드로 구현하면 다음과 같다.

 

 

public int solution(int[] people, int limit) {
        int answer = 0;
        Arrays.sort(people);
        Deque<Integer> deque = new LinkedList<>();
        for (int i = 0; i < people.length; i++) {
            deque.offer(people[i]);
        }
        int count = 0;
        while(!deque.isEmpty()) {
            int first = deque.pollFirst();
            while(!deque.isEmpty()) {
                int last = deque.pollLast();
                System.out.println("deque : "+deque+ "// ["+first+", "+last+"]");
                if (first+last <= limit) {
                    break;
                }
                count++;
            }
            count++;

        }
        System.out.println("count : "+count);
        answer = count;
        return answer;
    }