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);
}
}
'알고리즘' 카테고리의 다른 글
[백준/Java] 2457 : 공주님의 정원 (0) | 2025.02.17 |
---|---|
[백준/Java] 1541 : 잃어버린 괄호 (0) | 2025.02.17 |
[백준/Java] 2346 : 풍선 터뜨리기 (4) | 2025.02.17 |
[백준/Java] 1707 : 이분 그래프 (2) | 2025.02.17 |
[백준/Java] 11003 : 최솟값 찾기 (2) | 2025.02.17 |