코딩테스트
[프로그래머스 level2] 광물 캐기 자바 DFS / greedy 방식
mhui123
2025. 4. 20. 10:09
반응형
https://school.programmers.co.kr/learn/courses/30/lessons/172927
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제
@param picks [dia , iron, stone] 종류별 곡괭이 수
@param minerals [diamond, iron, stone] 으로 구성된 배열.
@return 채굴완료에 필요한 최소 피로도
접근 & 피드백
어떤 곡괭이를 차용하느냐에 따라 피로도가 다름. 곡괭이 순서를 조합하여 최소값을 구해야 하므로
DFS방식이나 GREEDY 정렬 방식을 사용할 수 있다고 한다.
1. DFS방식
// 1. picks = {dia, iron, stone} 곡괭이 수
// 2. 광물을 5개씩 묶어서 블록으로 만든다
// 3. 각 블록에 대한 피로도를 3종류 곡괭이로 미리 계산한다
// 4. DFS로 곡괭이 순서를 조합하며 최소 피로도 갱신
List<int[]> fatigueBlocks = new ArrayList<>();
int minFatigue = Integer.MAX_VALUE;
public int solution(int[] picks, String[] minerals) {
//각 곡괭이는 광물을 채집할 때 다음과 같은 피로도를 소모한다.
/*
다이아 -> : 다이아,철,돌 = 1
철 -> : 다이아 = 5, 철, 돌 = 1
돌 -> : 다이아 = 25, 철 = 5, 돌 = 1
*/
//모든 곡괭이는 광물 5개 채굴 후 파괴됨.
for(int i = 0; i < Math.min(minerals.length, (picks[0] + picks[1] + picks[2]) * 5); i += 5){
int[] fatigue = new int[3];
for(int j = i; j < i + 5 && j < minerals.length; j++){
String m = minerals[j];
fatigue[0] += 1; //다이아 곡괭이
fatigue[1] += m.equals("diamond") ? 5 : 1; //철 곡괭이
fatigue[2] += m.equals("diamond") ? 25 : m.equals("iron") ? 5 : 1; //돌 곡괭이
}
fatigueBlocks.add(fatigue);
}
// 2. DFS 시작
dfs(0, picks[0], picks[1], picks[2], 0);
return minFatigue;
}
void dfs(int idx, int d, int i, int s, int fatigueSum) {
if (idx == fatigueBlocks.size()) {
minFatigue = Math.min(minFatigue, fatigueSum);
return;
}
if (d > 0) dfs(idx + 1, d - 1, i, s, fatigueSum + fatigueBlocks.get(idx)[0]);
if (i > 0) dfs(idx + 1, d, i - 1, s, fatigueSum + fatigueBlocks.get(idx)[1]);
if (s > 0) dfs(idx + 1, d, i, s - 1, fatigueSum + fatigueBlocks.get(idx)[2]);
}
2.GREEDY 정렬방식
public int solution2(int[] picks, String[] minerals) {
int pickCount = picks[0] + picks[1] + picks[2];
int blockCount = Math.min(minerals.length / 5 + (minerals.length % 5 == 0 ? 0 : 1), pickCount);
List<int[]> fbs = new ArrayList<>();
for (int i = 0; i < blockCount; i++) {
int[] fatigue = new int[3]; // [dia, iron, stone]
for (int j = i * 5; j < i * 5 + 5 && j < minerals.length; j++) {
String m = minerals[j];
fatigue[0] += 1;
fatigue[1] += m.equals("diamond") ? 5 : 1;
fatigue[2] += m.equals("diamond") ? 25 : m.equals("iron") ? 5 : 1;
}
fbs.add(fatigue);
}
// 돌곡괭이 기준 피로도 내림차순 정렬
fbs.sort((a, b) -> b[2] - a[2]);
int fatigueSum = 0;
int blockIdx = 0;
// 좋은 곡괭이부터 사용
for (int i = 0; i < picks.length; i++) {
for (int j = 0; j < picks[i]; j++) {
if (blockIdx >= fbs.size()) break;
fatigueSum += fbs.get(blockIdx++)[i]; // i는 곡괭이 종류 index
}
}
return fatigueSum;
}
반응형