728x90
문제
접근 방식
주어진 수열에서 순서 상관 없이 수들을 더하거나 둘을 묶어서 곱하여
가장 큰 값을 얻기 위해서는 빼야 할 때는 가능한 가장 작은 수를
더해줄 때는 가장 큰 수를 더해줘야 한다.
두 수를 곱하는 경우를 생각해보면
음수 * 음수 = 양수
음수 * 0 = 0
양수 * 양수 = 양수
위와 같이 세 가지 경우가 있고
두 수를 더하는 경우를 생각해보면
양수 * 1 < 양수 + 1
양수 * 0 < 양수 + 0
위와 같은 경우가 있다.
좀 더 간단하게 정리해보면 아래와 같다.
// 음수로 만들 수 있는 최적의 해
음수 * 0이하의 수
// 양수로 만들 수 있는 최적의 해
양수 * 양수
양수 + 1
양수는 0과 곱하거나 더하는 경우에는 어떤 이득도 볼 수 없기 때문에
0은 위와 같이 음수와 처리해주는 것이 좋다.
수열을 입력 받을 때 0이하의 수가 등장할 때마다
따로 변수에 카운팅을 해준 후에
수열을 오름차순으로 정렬하면
0번 인덱스 부터 카운팅한 만큼까지가 0이하의 수에 해당하고
이후의 인덱스들은 모두 양수라는 것을 알 수 있다.
-3
-2
-1
위와 같은 수열이 주어졌을 때를 생각해보면
-3과 -2를 곱하여 6을 만들고 -1을 빼서 5를 얻는 경우가 최적의 해이고
-2
-1
위와 같은 경우는 둘이 그대로 곱해 2를 얻는 경우가 최적의 해인데
여기서 알 수 있는 것이 0이하의 개수가 홀수면
마지막 인덱스를 제외한 값들은 서로 곱하고 마지막만 빼주면 되고
개수가 짝수면 모두 서로 곱해주면 된다.
양수의 경우는 반대로 개수가 홀수면
첫 인덱스 값을 더해주고 나머지 값들을 서로 곱해주고
짝수면 모두 서로 곱해주면 된다.
이제 정리한 내용들을 토대로
0번 부터 COUNT - 1번 인덱스 까지의 음수들을 처리하는 부분과
COUNT번 부터 N - 1번 까지의 양수들을 처리하는 부분을 계산해주면 된다.
풀이
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int count = 0;
int[] seq = new int[n];
for (int i = 0; i < n; i++) {
int x = Integer.parseInt(br.readLine());
seq[i] = x;
if (x <= 0) count++;
}
Arrays.sort(seq);
long prev = -1001;
long sum = 0;
for (int i = 0; i < count; i++) {
int cur = seq[i];
if (i == count - 1 && count % 2 != 0) {
sum += cur;
continue;
}
if (prev < -1000) {
prev = cur;
continue;
}
sum += (prev * cur);
prev = -1001;
}
prev = -1001;
for (int i = count; i < n; i++) {
int cur = seq[i];
if (i == count && (n - count) % 2 != 0) {
sum += cur;
continue;
}
if (prev < -1000) {
prev = cur;
continue;
}
if (prev * cur == cur) sum += (prev + cur);
else sum += (prev * cur);
prev = -1001;
}
System.out.println(sum);
}
}
'Java > Algorithms' 카테고리의 다른 글
[백준] 18808번 : 스티커 붙이기 (0) | 2024.01.19 |
---|---|
[백준] 1700번 : 멀티탭 스케줄링 (0) | 2024.01.17 |
[백준] 2170번 : 선 긋기 (1) | 2024.01.11 |
[백준] 2457번 : 공주님의 정원 (0) | 2024.01.10 |
[백준] 1541번 : 잃어버린 괄호 (0) | 2024.01.10 |