https://www.acmicpc.net/problem/2104
먼저 로직은 간단하다.
가운데를 기준으로 왼쪽 오른쪽을 재귀를 통해 나눈뒤, 각 재귀에서 (합 * 최소값)을 구한 뒤 최대값인지 비교를 하면 된다.
하지만, 자바로 직접 작성해보니 정 가운데 값 기준으로 왼쪽 인덱스와 오른쪽 인덱스를 늘려가면서 값 기준으로 정렬하다보니 예외가 발생한 것 같다. (틀렸다)
그래서 기준을 추가하였다.
이전 로직은 가운데 기준으로 왼쪽 오른쪽 인덱스를 하나씩 늘린값을 비교하였지만,
이번 로직은 가운데 로직과 오른쪽 인덱스를 비교하면서 시작한다.
import java.util.Scanner;
public class Num2104 {
public static int N;
public static long Num[];
public static long Max;
public static void main(String[] args) {
//input
Scanner scanner = new Scanner(System.in);
N = Integer.parseInt(scanner.nextLine());
Num = new long[N];
String[] a = scanner.nextLine().split(" ");
for (int i=0; i<N; i++) {
Num[i] = Long.parseLong(a[i]);
}
//logic
Max = Math.max(input(0, N-1), input1(0, N-1));
//output
System.out.println(Max);
}
public static long input(int start, int end) {
if (start > end)
return -1;
if (start == end)
return Num[start] * Num[start];
int mid = (start + end) / 2;
long max = Math.max(input(start, mid), input(mid+1, end));
int left = mid;
int right = mid+1;
long sum = Num[left] + Num[right];
long min = Math.min(Num[left], Num[right]);
max = Math.max(max, min * sum);
while (left > start || right < end) {
if (right < end && (left == start || Num[left-1] < Num[right+1])) {
right++;
sum += Num[right];
min = Math.min(min, Num[right]);
} else {
left--;
sum += Num[left];
min = Math.min(min, Num[left]);
}
max = Math.max(max, min * sum);
}
return max;
}
public static long input1(int start, int end) {
if (start > end)
return -1;
if (start == end)
return Num[start] * Num[start];
int mid = (start + end) / 2;
long max = Math.max(input1(start, mid-1), input1(mid+1, end));
long sum = Num[mid];
long min = Num[mid];
int left = mid;
int right = mid;
while (right - left < end - start) {
long leftValue;
long rightValue;
if (left > start)
leftValue = Num[left-1];
else
leftValue = -1;
if (right < end)
rightValue = Num[right+1];
else
rightValue = -1;
if (leftValue > rightValue) {
sum += leftValue;
min = Math.min(min, leftValue);
left--;
} else {
sum += rightValue;
min = Math.min(min, rightValue);
right++;
}
max = Math.max(max, sum * min);
}
return max;
}
}