1. ๋ฌธ์ ์ค๋ช
(1) ์ผ๊ฑฐ๋ฆฌ์ ์์ ์๊ฐ
, ๋ ์๊ฐ
, ์ผ์ ๋๋์ ๋์ ์ด์ต
์ด ์ฃผ์ด์ง๋ค.
(2) ์์ ์๊ฐ๊ณผ ๋ ์๊ฐ์ ๋ฒ์๊ฐ ๊ฒน์น๋ ์ผ์ ๊ฐ์ด ํ์ง ๋ชปํ๋ค. ๋ฐ๋ฉด ์ด๋ค ์ผ์ด ๋๋์๋ง์ ๋ค๋ฅธ ์ผ์ ์์ํ ์ ์๋ค.
์๋ฅผ ๋ค์ด, job A์ ๋ ์๊ฐ์ด 3์ ์ด๊ณ job B์ ์์์๊ฐ์ด 3์์ด๋ฉด ๋ ์ผ ๊ฑฐ๋ฆฌ๋ ์ฐ๋ฌ์ ํ ์ ์๋ค. ๋ฐ๋ฉด job C๊ฐ 3~5์์ด๊ณ job D๊ฐ 4~6์์ด๋ฉด ๋ ์ผ์ ์ผ์ ์๊ฐ ๋ฒ์๊ฐ ๊ฒน์น๋ฏ๋ก ๊ฐ์ดํ์ง ๋ชปํ๋ค.
(3) ์ด๋, ๊ฒน์น์ง ์๊ฒ ์ผ์ ํด์, ์ต๋ ์ด์ต
์ ์ป์ผ๋ ค๊ณ ํ๋ค. ์ฃผ์ด์ง ์ผ๊ฑฐ๋ฆฌ๋ค ์ค์์ ๊ฐ์ง ์ ์๋ ์ต๋ ์ด์ต
์ ๋ช์ธ๊ฐ?
2. ์ ๊ทผ ๋ฐฉ์
KEY WORD
: DP
(1) ์ฃผ์ด์ง ๋ฌธ์ ๊ฐ ์์์๊ฐ
, ๋์๊ฐ
, ์ด์ต
์ ๋ฐ๋ก ๋ฐ๋ก ์ฃผ๊ธฐ์ ์ด๋ฅผ ํ๋์ ์ผ(job) ๋จ์
๋ก ํ๋๋ก ๋ฌถ๋๋ค.
(2) ๋ฌถ์ธ job๋ค์ ํ๋์ ๋ฐฐ์ด๋ก ์ ์ฅํ๋ค. ์ด๋ ๋ฐฐ์ด์ ์์ ์๊ฐ ๊ธฐ์ค
์ผ๋ก ์ ๋ ฌ ํ๋ค.
(3) DP์ฉ ๋ฐฐ์ด์ ๋ง๋ ๋ค. (์ฌ๊ธฐ์๋ ์ด๋ฆ์ maxProfit ์ด๋ผ๊ณ ํ์.)
Top-down ๋ฐฉ์(๋งจ ๋์์ ๋ถํฐ ์์์ ์ผ๋ก ์ญํ) ์ ์ฐ๋ ค๊ณ ํ๋ค. ์ด๋ฌ๋ฉด maxProfit[0]์ ๋ชจ๋ ์ผ๊ฑฐ๋ฆฌ์ ์ต๋์ด์ต์ด ์ ์ฅ๋ ๊ฒ์ด๋ค.
DP๋ฅผ ์งํํ๋ ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ๋ค. ๋ง์ฝ ํ์ฌ๊ฐ maxProfit[k]์ ๊ฐ์ ์ ํด์ผ ํ๋ค๋ฉด,
- ํ์ฌ ์กฐํ ์ค์ธ
k
๋ฒ์งธ ์ผ๊ฑฐ๋ฆฌ๋ฅผ ๊ฑด๋ ๋ฐ๊ณ , ๊ทธ ์ ๊น์ง์ ์ต๋ ์ด์ต์ ๋ต์ตํ๋ค.
(maxProfit[k] = maxProfix[k+1]) - ํ์ฌ ์กฐํ ์ค์ธ k ๋ฒ์งธ ์ผ์ ํ๊ณ ์ด์ต์ ์ป๋๋ค. ์ด๋ ๊ฒฐ๊ณผ๊ฐ ์ต๋ ์ด์ต์ด ๋๋ ค๋ฉด ๊ทธ ์ ๊ฐ๋ค ์ค
์๊ฐ๋๊ฐ ๊ฒน์น์ง ์๋ ์
์์ ์ต๋ ์ด์ต์ ๋์ ํด์ผ ํ๋ค.
(maxProfit[k] = job[k] [2] (ํ ์ด์ต) + maxProfit[nonOverLappingIndex]) - ์์ ๋ ๊ฐ ์ค ์ต๋๊ฐ์ ๊ตฌํ๋ค.
โจ ํ๋ฒ ํด๋ณด๊ธฐ
๊ทธ๋ผ ์์ ์์๋ก maxProfit[4] -> maxProfit[0]๊น์ง ๊ตฌํด๋ณด๊ฒ ๋ค.
(1) maxProfit[4]๋ ์๋์ ๋ฐฐ์ด์ ์๋ ๊ฐ์ด๋ค. ํด๋น ์์น๋ ๋ฐฐ์ด์ ๋ฒ์ด๋ OutOfIndex๊ฐ ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด์ ๋ฃ์๋ค. ๋ฐ๋ผ์ 0์ ์ ๋ ฅํ๋ค.
(2) maxProfit[3] ์ ํ์ฌ ์์ ์ ์ผ์ ํ์ง ์๊ณ , ์ด์ ๊ฐ ์ค ์ต๋๊ฐ ๋ต์ต(value = 0) ํน์ ํ์ฌ ์์ ์ ์ผ์ ํ๊ณ ๊ฒน์น์ง ์๋ ์ ์์ ์ต๋๊ฐ ๋์ ํ๊ธฐ(๊ทธ ์ด์ ์ ๊ฒน์น์ง ์๋ ๊ฐ์ด ์์ผ๋ฏ๋ก ๊ทธ๋ฅ 70 )์ด ๋์ค๋๋ฐ, 70์ด ์ต๋ ๊ฐ์ด๋ค.
(3) maxProfit[2] = ์ด์ ๊ฐ ๋ต์ต ์ 70, ์๊ธฐ ์์ ์ ์ผ์ ํ๊ณ ๊ฒน์น์ง ์๋ ์ ์์ ์ต๋๊ฐ ๋ ํ ์ 40+0 ์ด ๋์ด 70์ด ๋๋ค.
Job[2]๋ฅผ ๋ณด๋ฉด ์ผ์ด 4์์ ๋ง์น๋๋ฐ, 4์ ์ดํ์ ํ ์ ์๋ ๋ค๋ฅธ ์ผ์ด ์๊ธฐ ๋๋ฌธ์ ๊ฒน์น์ง ์๋ ์ ์์ ๋ ํ ์ผ์ด ์๋ค.
(4) maxProfit[1] = Math.max(70,10) ์ด๋ค.
(5) ์ด์ ์ผ ์ ๋๋ก ๋ณด์ด๊ฒ ๋ค.
maxProfit[0] = (70, 50 + 70) = 120 ์ด๋ค.
Job[0]์ ๋ณด๋ฉด, 3์์ ์ผ์ ๋๋ด๋๋ฐ, 3์ ์ดํ์ ์ด์ต ์ค ์ต๋ ์ด์ต์ด 70์ด์ฌ์ ๊ทธ ๊ฐ์ ๋ํ๋ฉด ๋๋ค.
โจ nonOverLappingIndex๋ ์ด๋ป๊ฒ ์ฐพ์๊น?
๊ฒน์น์ง ์๋ index๋ฅผ ์ด๋ป๊ฒ ์ฐพ์๊น? ์ด๋ถ ํ์์ ํ์ฉํ๋ ๋ฐฉ๋ฒ๋ ์์ง๋ง, TreeMap์ ์ฌ์ฉํ๋ฉด ํจ์ฌ ์ฝ๋ค.
TreeMap์ Key๋ ์์์๊ฐ, value ๋ index๋ก ๋๋ค. ์ด๋ฌ๋ฉด ์์์๊ฐ์ด ๋น ๋ฅธ ์์ผ๋ก ์ ๋ ฌ๋ ๊ฒ์ด๋ค. ์ฐ๋ฆฌ๋ ์ด๋, TreeMap์ ํจ์ ์ค ํ๋์ธ ceilingEntry(Key k)
๋ผ๋ ํจ์๋ฅผ ์ฌ์ฉํ๋ค. ํด๋น ํจ์๋ ์ธ์๋ก ๋ค์ด์จ key ๊ฐ ๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์(greater) ๊ฐ ์ค์์ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ฐ
์ ๋ฐํํ๋ ํจ์์ด๋ค.
์๊น TreeMap์ Key๋ฅผ ์์์๊ฐ์ผ๋ก ํ์์ผ๋ก, ceilingEntry(ํ์ฌ ์กฐํ ์ค์ธ ์ผ์ ๋์๊ฐ)
์ ๋ฃ์ผ๋ฉด ๊ทธ๊ฒ๋ณด๋ค ๋ฆ๊ฒ ์์ ํ๋ ์ผ ์ค ๊ฐ์ฅ ๋น ๋ฅธ ์๊ฐ๋์ ์ผ์ ๋ฐํํ ๊ฒ์ด๋ค. ์ด๋ฅผ ์ด์ฉํ์ฌ nonOverLappingIndex๋ฅผ ์ฐพ๋๋ค.maxProfit[nonOverLappingIndex]
๋ฅผ ํ๋ฉด, ๊ฒน์น์ง ์๋ ์๊ฐ๋ ์ค ๊ฐ์ฅ ๋น ๋ฅธ ์๊ฐ๋์ ์ต๋ ์ด์ต์ ์ป์ ์ ์๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์์ฐจ๊ฒ ์ง๊ธ๊น์ง์ ์ต๋ ์ด์ต์ ๋์ ์ํฌ ์ ์๋ ๊ฒ์ด๋ค.
TreeMap์ด๋?
3. ์ฝ๋ ๋ถ์
import java.io.*;
import java.util.*;
class Solution {
public int jobScheduling(int[] startTime, int[] endTime, int[] profit) {
// 1. ๊ฐ ํ๋๋ก ๋ชจ์ผ๊ธฐ
int merged[][] = new int [startTime.length][3];
for(int i = 0; i < startTime.length; i++){
merged[i] = new int []{startTime[i], endTime[i], profit[i]};
}
Arrays.sort(merged, (a,b) -> Integer.compare(a[0], b[0]));
// 2. dp ๋ฐฐ์ด ๋ง๋ค๊ธฐ
// ๋ฐฐ์ด์ ๋๋ณด๋ค ๊ทธ ๋ค์์๋ถํฐ ์์ํด์ผํจ์ผ๋ก ํ ์นธ ๋
int [] maxProfit = new int [merged.length + 1];
// 3. ๊ฒน์น์ง ์๋ ๊ฐ์ฅ ๋น ๋ฅธ ์๊ฐ๋ ๊ตฌํ๊ธฐ ์ฉ
TreeMap<Integer, Integer> startTimeToIndex = new TreeMap<>();
// 4. top-down dp
for(int i = startTime.length - 1; i >= 0; i--){
// 3๋ฒ์ ๊ฐ ๊ตฌํ๊ธฐ
Integer nextNonOverlappingIndex = java.util.Optional.ofNullable(
startTimeToIndex.ceilingEntry(merged[i][1])
).map(e -> e.getValue()).orElse(startTime.length);
maxProfit[i] = Math.max(
maxProfit[i+1], // ์ด๋ฒ ๊บผ Skipํ๊ณ , ์ด์ ๊ฐ ์ค ์ ์ผ ํฐ ๊ฐ ๊ฐ์ ธ์ค๊ธฐ
merged[i][2] + maxProfit[nextNonOverlappingIndex] // ํ์ฌ ์ด์ต + ๊ฒน์น์ง ์๋ ์ ์ผ ๊ฐ๊น์ด ์์น์ ์ต๋๊ฐ ๊ฐ์ ธ์ค๊ธฐ
);
// 5. ํ์ฌ ๊ฐ ๋ค ๊ตฌํ์ผ๋ฉด, ๊ฒน์น์ง ์๋ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ฐ ๊ตฌํ๊ธฐ ์ํด TreeMap์ ๋ฃ๊ธฐ
startTimeToIndex.put(merged[i][0], i);
}
return maxProfit[0];
}
}
4. ์ฑ์ฅ ํ๊ธฐ
๋ ์ด๋ ค์์ ๋ค๋ฅธ ์ฌ๋ ํ์ด๋ฅผ ๋ดค๋ค. LeetCode๊ฐ ํ๊ตญ ํ์ด๊ฐ ์ ์์ด, ์ธ๊ตญ์ธ ํ์ด๋ฅผ ๋ณด๋๋ผ ํด๋ฉจ๋ค.