알고리즘

[백준/Java] 1744 : 수 묶기

Stitchhhh 2025. 2. 17. 06:35

https://www.acmicpc.net/problem/1744

 

이번 문제는 그리디 알고리즘입니다. 그리디 알고리즘은 귀류법을 통해 증명을 해놓는 습관이 중요합니다. 가설은 다음과 같습니다.

  • 양수 영역은 내림차순으로 2개씩 곱한 합과 양수의 개수가 홀수 일 경우 남은 값을 더합니다.
  • 음수 영역은 오름차 순으로 2개씩 곱한 합과 만일 음수 영역의 값이 홀수 일 경우 0의 존재 유무를 확인해 존재한다면 그 음수를 음수 으로 제거하고 없다면 음수를 더합니다.

양수 영역부터 명제를 확인해보겠습니다. 만약 양수 부분에서 내림차 순으로 2개씩 곱하지 않았을 때 최대값이 나온다면 명제는 틀린 것이 됩니다.


양수가 9, 8, 7, 6이 있을 때 2개씩 곱한 값으로 대체 할 수 있다면 이 제일 큽니다.


그런데 여기서  등 다르게 계산한 것은 모두 위에 계산보다 작을 것이므로 명제는 참이라 할 수 있습니다. 음수도 이와 마찬가지로 증명이 됩니다.

 

앞선 명제를 바탕으로 우선순위 큐를 활용해 계산을 하면 쉽게 해결할 수 있습니다.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.PriorityQueue;

public class Backjoon_1744_수_묶기 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());

        PriorityQueue<Integer> pq1 = new PriorityQueue<>(Collections.reverseOrder());
        PriorityQueue<Integer> pq2 = new PriorityQueue<>();

        int count = 0;

        for(int i = 0 ; i < N ; i++){
            int value = Integer.parseInt(br.readLine());
            if(value > 0){
                pq1.offer(value);
            }else if(value < 0){
                pq2.offer(value);
            }else{
                count++;
            }

        }

        int answer = 0;

        while(pq1.size() > 1){
            Integer first = pq1.poll();
            Integer second = pq1.poll();

            answer += Math.max(first * second , first + second);
        }

        if(!pq1.isEmpty()){
            answer += pq1.poll();
        }

        while(pq2.size() > 1){
            Integer first = pq2.poll();
            Integer second = pq2.poll();

            answer += Math.max(first * second , first + second);
        }

        if(!pq2.isEmpty()){
            if(count == 0){
                answer += pq2.poll();
            }
        }
        System.out.println(answer);
    }
}