알고리즘 공부
99클럽 코테 스터디 29일차 TIL
HD9504
2024. 8. 19. 22:35
오늘의 학습 키워드
- 동적 프로그래밍 (Dynamic Programming)
- 작업 스케줄링 (Job Scheduling)
- 최적화 문제 해결
문제 이해
이 문제는 여러 작업이 주어졌을 때, 서로 겹치지 않도록 작업을 선택해 최대 이익을 얻는 문제입니다. 각 작업은 시작 시간, 종료 시간, 그리고 해당 작업을 수행했을 때 얻는 이익이 주어지며, 가능한 작업 조합 중에서 이익이 가장 큰 조합을 찾는 것이 목표입니다.
나의 풀이
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] startTime = {1, 1, 1};
int[] endTime = {2, 3, 4};
int[] profit = {5, 6, 4};
System.out.println(jobScheduling(startTime, endTime, profit));
}
public static int jobScheduling(int[] startTime, int[] endTime, int[] profit) {
int n = startTime.length;
int[] memo = new int[n + 1];
int[][] jobs = new int[n][3];
for (int i = 0; i < n; i++) {
jobs[i] = new int[]{startTime[i], endTime[i], profit[i]};
}
// 종료 시간 기준으로 정렬
Arrays.sort(jobs, (a, b) -> a[1] - b[1]);
for (int i = 0; i < n; i++) {
memo[i + 1] = Math.max(memo[i], jobs[i][2]);
for (int j = i - 1; j >= 0; j--) {
// 종료 시간이 다음 작업의 시작 시간보다 작거나 같으면
if (jobs[j][1] <= jobs[i][0]) {
int prev = memo[i + 1]; // 현재 작업까지의 최대 이익
int current = memo[j + 1] + jobs[i][2]; // 이전 작업까지의 최대 이익 + 현재 작업의 이익
memo[i + 1] = Math.max(prev, current);
break;
}
}
}
return memo[n];
}
}
풀이 설명
작업 정보 초기화
- 주어진 작업의 시작 시간, 종료 시간, 이익을
jobs
배열에 저장합니다. 이 배열은 각 작업을{시작 시간, 종료 시간, 이익}
의 형태로 저장합니다.
- 주어진 작업의 시작 시간, 종료 시간, 이익을
작업 정렬
- 작업을 종료 시간 기준으로 정렬합니다. 이는 먼저 끝나는 작업을 우선 선택함으로써, 최대한 많은 작업을 선택할 수 있도록 하기 위함입니다.
동적 프로그래밍 배열 초기화
memo
배열은 각 작업까지의 최대 이익을 저장합니다.memo[i]
는i
번째 작업까지 선택했을 때의 최대 이익을 의미합니다.
최대 이익 계산
- 각 작업을 순회하면서, 해당 작업을 선택했을 때와 선택하지 않았을 때의 최대 이익을 비교합니다.
- 선택할 경우, 해당 작업 이전에 끝나는 작업들 중에서 가장 큰 이익을 더하여 계산합니다.
- 이 과정을 통해, 현재 작업까지의 최대 이익을
memo
배열에 저장합니다.
결과 반환
- 최종적으로,
memo[n]
에 저장된 값이 주어진 작업들에서 얻을 수 있는 최대 이익입니다.
- 최종적으로,
예제 설명
예를 들어, 주어진 작업이 다음과 같다고 가정합니다:
- 시작 시간:
[1, 1, 1]
- 종료 시간:
[2, 3, 4]
- 이익:
[5, 6, 4]
이 경우, 종료 시간 기준으로 작업을 정렬하면 [1, 2, 5]
, [1, 3, 6]
, [1, 4, 4]
가 됩니다.
동적 프로그래밍을 통해 각 작업까지의 최대 이익을 계산하면, 결과적으로 얻을 수 있는 최대 이익은 6
이 됩니다.