[Java]그리디 알고리즘 - 배열에서 2개씩 짝지을때 합의 최댓값이 최소가 되게할려면
1. 문제
"""
2 * N개의 숫자가 주어졌을 때, 겹치지 않으면서 2개의 원소가 하나의 그룹을 이루도록 하여 총 N개의 그룹을 만드려고 합니다. 적절하게 그룹을 만들어 각 그룹에 있는 원소의 합 중 최댓값이 최소가 되도록 하는 프로그램을 작성해보세요.
예를 들어 N = 2, 주어진 원소가 3, 5, 5, 2 였을 때
그룹을 [5, 5], [3, 2]로 나눈다면 각 그룹에 있는 원소의 합은 순서대로 10, 5 이므로 이 중 최댓값은 10이 됩니다.
만약 그룹을 [3, 5], [5, 2]로 나눈다면 각 그룹에 있는 원소의 합은 순서대로 8, 7 이 되므로 이 중 최댓값은 8이 되며 이보다 최댓값을 더 작게 만들 수는 없습니다.
"""
2. 풀이
항상 문제부터 똑바로 이해해야돼
2N개의 숫자를 N개 N개씩 2개 그룹으로 나누는게 아니라... 2개씩 짝지어서, N개 그룹을 만들려는게 핵심이고
어떻게 2개씩 짝지어야, N개 그룹들에서 합의 최댓값이 최소가 될 수 있을까
그거는 매 순간, 최댓값과 최솟값을 짝지어야 전체 N개 그룹에서 합의 최댓값이 최소가 될 수 있다.
왜냐하면,
N개의 수를 오름차순으로 정렬해서 $a_{1}, a_{2}, ... , a_{N}$으로 만들었다고 했을 때,
$a_{N}$은 어떠한 수 보다도 더 크다.
남은 하나와 짝을 지었을때, 어떠한 수와 짝을 지어야 합이 가장 작아질 수 있을까?
당연히 $a_{1}$이다.
마찬가지로 $a_{2}, ..., a_{N-1}$에서 $a_{N-1}$은 현재 어떠한 수보다도 더 크다.
그렇다면 어떠한 수와 짝을 지어야 합이 가장 작아지는가?
당연히 $a_{2}$이다.
따라서 매 순간 배열에 남은 수에서 최댓값과 최솟값을 묶어야, 두 수의 합이 가장 작아질 수 있다.
그리고 이렇게 묶어야 전체 N개의 그룹을 만들었을 때, 이들 각각 그룹의 합의 최댓값은 모든 경우에서 가장 작아진다.
실제로
[a2,aN], [a1,aN-1] 을 생각해보자.
여기서 합의 최대는 a2+aN이다.
이번엔, a1과 a2를 바꿔서 [a1,aN], [a2,aN-1] 으로 해보면, a1+aN과 a2+aN-1 모두 합의 최대가 될 수 있지만
이들은 a2+aN보다 작다.
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 여기에 코드를 작성해주세요.
Scanner sc = new Scanner(System.in);
int n = 2*sc.nextInt();
int[] arr = new int[n];
for(int i = 0; i < n; i++){
arr[i] = sc.nextInt();
}
Arrays.sort(arr);
int max = 0;
for(int i =0; i<n; i++){
int sum = arr[i] + arr[n-1-i];
if(max < sum){
max = sum;
}
}
System.out.println(max);
}
}
명확히 일반적인 경우에서 증명이 안된 느낌인데
직관은 맞는데
'알고리즘 > 그리디 알고리즘' 카테고리의 다른 글
경이로운 그리디 알고리즘2 -인접한 원소간 차이로 그룹을 나누는 방법- (0) | 2023.05.31 |
---|---|
문자열 그리디 연습1 - 최소 횟수로 교환해서 두 문자열 같게 만들기 (0) | 2023.05.16 |
그리디 알고리즘 - 거리의 합이 최소가 되는 위치를 찾는 방법 (0) | 2023.01.27 |
그리디 알고리즘 한층 더 깊게 생각하는법 배우기 -선물할인- (0) | 2023.01.21 |
그리디 알고리즘 연습하기2 -잃어버린 괄호- (0) | 2023.01.19 |