N개의 직사각형 블록으로 두 개의 탑을 만들되, 두 탑의 높이를 같게 하면서 가능한 최대 높이를 구하는 문제를 풀어봤다. 이 문제는 각 블록의 높이를 합쳐서 특정 높이의 차이를 최소화하는 방식으로 접근할 수 있다. 동적 계획법(DP)을 사용해 부분합의 차이를 조절하는 방식으로 풀이했다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
static int[] blocks;
static int[][] dp;
static int N;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 블록의 개수 입력
N = Integer.parseInt(br.readLine());
blocks = new int[N];
// 블록 높이 입력
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
blocks[i] = Integer.parseInt(st.nextToken());
}
// dp 배열 초기화
dp = new int[N + 1][500001];
for (int[] row : dp) {
Arrays.fill(row, -1);
}
int answer = findMaxHeight(0, 0);
System.out.println(answer > 0 ? answer : -1);
}
// 다이나믹 프로그래밍을 통해 최대 탑 높이 계산
static int findMaxHeight(int index, int diff) {
if (index == N) {
return (diff == 0) ? 0 : Integer.MIN_VALUE;
}
if (dp[index][diff] != -1) {
return dp[index][diff];
}
int skip = findMaxHeight(index + 1, diff); // 현재 블록을 사용하지 않는 경우
int addToTaller = findMaxHeight(index + 1, diff + blocks[index]) + blocks[index]; // 더 높은 탑에 현재 블록 추가
int addToShorter = findMaxHeight(index + 1, Math.abs(diff - blocks[index])) + (diff > blocks[index] ? 0 : blocks[index] - diff); // 더 낮은 탑에 현재 블록 추가
dp[index][diff] = Math.max(skip, Math.max(addToTaller, addToShorter));
return dp[index][diff];
}
}
N = Integer.parseInt(br.readLine());
blocks = new int[N];
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
blocks[i] = Integer.parseInt(st.nextToken());
}
dp = new int[N + 1][500001];
for (int[] row : dp) {
Arrays.fill(row, -1);
}
static int findMaxHeight(int index, int diff) {
if (index == N) {
return (diff == 0) ? 0 : Integer.MIN_VALUE;
}
if (dp[index][diff] != -1) {
return dp[index][diff];
}
코드 복사
int skip = findMaxHeight(index + 1, diff); // 현재 블록을 사용하지 않는 경우
int addToTaller = findMaxHeight(index + 1, diff + blocks[index]) + blocks[index]; // 더 높은 탑에 현재 블록 추가
int addToShorter = findMaxHeight(index + 1, Math.abs(diff - blocks[index])) + (diff > blocks[index] ? 0 : blocks[index] - diff); // 더 낮은 탑에 현재 블록 추가
코드 복사
dp[index][diff] = Math.max(skip, Math.max(addToTaller, addToShorter));
return dp[index][diff];
코드 복사
int answer = findMaxHeight(0, 0);
System.out.println(answer > 0 ? answer : -1);
이 문제는 DP를 활용해 모든 블록을 선택하거나 선택하지 않으면서 두 탑의 높이를 맞추는 문제였다. 특히, 두 탑의 높이 차이를 상태로 유지하면서 각 블록을 배치하는 방법으로 최적해를 구했다.