#
문제 설명
곡괭이로 광산에서 규칙을 지키면서
최소한의 피로도로 광물을 캐기
조건
피로도 소모
다이아 | 철 | 돌 | |
---|---|---|---|
다이아 | 1 | 1 | 1 |
철 | 5 | 1 | 1 |
돌 | 25 | 5 | 1 |
매개 변수
picks
minerals
반환값
picks는 [dia, iron, stone]
minerals는 다음 3개의 문자열
picks | minerals | result |
---|---|---|
[1, 3, 2] | ["diamond", "diamond", "diamond", "iron", "iron", "diamond", "iron", "stone"] | 12 |
[0, 1, 1] | ["diamond", "diamond", "diamond", "diamond", "diamond", "iron", "iron", "iron", "iron", "iron", "diamond"] | 50 |
function solution(picks, minerals) {
let answer = 25 * minerals.length;
const dfs = (p_arr, m_arr, fatigue) => {
if (p_arr.every(v => v === 0) || !m_arr.length) {
answer = Math.min(answer, fatigue);
return;
}
const [dia, iron, stone] = p_arr;
// 다이아 곡괭이 있을 때
if (dia > 0) {
const nextP = [dia-1, iron, stone];
const nextM = m_arr.slice(5);
const nextF = fatigue + (m_arr.length - nextM.length);
dfs(nextP, nextM, nextF);
}
let countM = [0, 0, 0];
m_arr.slice(0, 5).forEach((v) => {
if (v === "diamond") countM[0] += 1;
else if (v === "iron") countM[1] += 1;
else countM[2] += 1;
});
// 철 곡괭이 있을 때
if (iron > 0) {
const nextP = [dia, iron-1, stone];
const nextM = m_arr.slice(5);
const nextF = fatigue + (countM[0] * 5 + countM[1] + countM[2]);
dfs(nextP, nextM, nextF);
}
// 돌 곡괭이 있을 때
if (stone > 0) {
const nextP = [dia, iron, stone-1];
const nextM = m_arr.slice(5);
const nextF = fatigue + (countM[0] * 25 + countM[1] * 5 + countM[2]);
dfs(nextP, nextM, nextF);
}
}
dfs(picks, minerals, 0);
return answer;
}
풀이
- DFS 완전 탐색을 통해 solution 구하기
- answer 은 피로도의 최솟값을 담기 위해
반환 가능한 피로도 최댓값으로 초기화
- 주어진 광물에 순서대로 광물을 캐고
조건에 따라 피로도가 달리 발생하고
최솟값을 구하기 때문에 완전 탐색
- 탐색을 종료하는 조건
- 곡괭이가 고갈될 때
- 광석을 모두 캤을 때
- 각각 곡괭이로 캤을 때 DFS 탐색
성능 더 좋은 다른 사람 풀이 (그리디)
function solution(picks, minerals) {
const remainPicks = [...picks];
const maxFatigue = [];
const useable = minerals.slice(0, picks.reduce((acc, cur) => acc + cur) * 5);
useable.forEach((mineral, index) => {
if (index % 5 === 0) maxFatigue.push({"diamond": 0, "iron": 0, "stone": 0});
maxFatigue.at(-1)[mineral] ++;
})
maxFatigue.sort((a, b) => (b.diamond * 25 + b.iron * 5 + b.stone) - (a.diamond * 25 + a.iron * 5 + a.stone))
const answer = maxFatigue.reduce((acc, {diamond, iron, stone}) => {
if (remainPicks[0] !== 0) {
remainPicks[0] --;
return acc + diamond + iron + stone;
} else if (remainPicks[1] !== 0) {
remainPicks[1] --;
return acc + diamond * 5 + iron + stone;
} else {
remainPicks[2] --;
return acc + diamond * 25 + iron * 5 + stone;
}
}, 0)
return answer;
}