Programmers-구명보트

2020-08-28

위 문제는 Programmers 구명보트 문제에 관한 설명입니다.


문제

무인도에 갇힌 사람들을 구명보트를 이용하여 구출하려고 합니다.

구명보트는 작아서 한 번에 최대 2명씩 밖에 탈 수 없고, 무게 제한도 있습니다.

예를 들어, 사람들의 몸무게가 [70kg, 50kg, 80kg, 50kg]이고

구명보트의 무게 제한이 100kg이라면 2번째 사람과 4번째 사람은 같이 탈 수 있지만

1번째 사람과 3번째 사람의 무게의 합은 150kg이므로 구명보트의 무게 제한을

초과하여 같이 탈 수 없습니다.

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

사람들의 몸무게를 담은 배열 people과 구명보트의 무게 제한 limit가 매개변수로 주어질 때,

모든 사람을 구출하기 위해 필요한 구명보트 개수의 최솟값을 return 하도록

solution 함수를 작성해주세요.

제한사항

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

입출력 예제

people limit return
[70, 50, 80, 50] 100 3
[70, 80, 50] 100 3
import java.util.Arrays;
class Solution {
	public int solution(int[] people, int limit) {
		int answer = 0;
		int i = 0;
		Arrays.sort(people);
		for(int j=people.length-1; i<=j; j--) {
			if(people[j] + people[i] > limit)
				answer ++;
			else {
				answer ++;
				i ++;
			}
		}
		return answer;
	}

}


이번 문제는 Greedy 문제였습니다.

구명보트는 최대 2명씩 밖에 탈 수 없고 무게 제한이 정해져 있습니다.

가장 적은양의 보트로 최대한 태우기 위해서는

가장 작은 몸무게가장 큰 몸무게의 합 < 무게 제한 인가를 판단하는 것이 좋습니다.

그럼 어떻게 풀어야 할까?

바로 정렬을 하는 것입니다.

people[]을 무게순서대로 오름차순 하기 위해

 Arrays.sort(people);

첫번째 예시를 적용시켜보면

[70, 50, 80, 50] 에서 [50, 50, 70, 80]이 됩니다.

		int i = 0;
		for(int j=people.length-1; i<=j; j--) {
			if(people[j] + people[i] > limit)
				answer ++;
			else {
				answer ++;
				i ++;
			}
		}

분기문을 봅시다.

소스코드는 이렇게 되어있습니다.

i는 인덱스를 나타내기 위함인데 이것은 잠시 미뤄두고,

분기문의 j 부터 살펴봅시다.

jpeople.length-1부터 시작하는데 이것은 가장 큰 몸무게의 사람을 뜻합니다.

이후 j는 무게가 적은 사람으로 점점 넘어갑니다.

조건문도 함께 봅시다.

people[j]는 맨뒤에서 부터 몸무게가 가장 큰 사람

people[i]는 맨앞에서 부터 몸무게가 가장 작은 사람

이 둘의 합이 무게제한 보다 크다면 보트 갯수를 하나 더 구해와야하기 때문에 설정해줍니다.

무게 제한보다 작다면? 그 둘이 타는 보트를 1개 구해오고 i++를 통해

인덱스가 가장 작은 사람에서 다음번쨰로 작은 사람부터 시작하게 되고,

몸무게 가장 큰 사람도 그 다음으로 무게가 나가는 사람으로 넘어가게 됩니다.

이 과정을 반복하는 분기문으로 문제를 해결할 수 있었습니다.

구명보트