https://programmers.co.kr/learn/courses/30/lessons/87946?language=javascript
XX게임에는 피로도 시스템(0 이상의 정수로 표현합니다)이 있으며, 일정 피로도를 사용해서 던전을 탐험할 수 있습니다. 이때, 각 던전마다 탐험을 시작하기 위해 필요한 "최소 필요 피로도"와 던전 탐험을 마쳤을 때 소모되는 "소모 피로도"가 있습니다. "최소 필요 피로도"는 해당 던전을 탐험하기 위해 가지고 있어야 하는 최소한의 피로도를 나타내며, "소모 피로도"는 던전을 탐험한 후 소모되는 피로도를 나타냅니다. 예를 들어 "최소 필요 피로도"가 80, "소모 피로도"가 20인 던전을 탐험하기 위해서는 유저의 현재 남은 피로도는 80 이상 이어야 하며, 던전을 탐험한 후에는 피로도 20이 소모됩니다.
이 게임에는 하루에 한 번씩 탐험할 수 있는 던전이 여러개 있는데, 한 유저가 오늘 이 던전들을 최대한 많이 탐험하려 합니다. 유저의 현재 피로도 k와 각 던전별 "최소 필요 피로도", "소모 피로도"가 담긴 2차원 배열 dungeons 가 매개변수로 주어질 때, 유저가 탐험할수 있는 최대 던전 수를 return 하도록 solution 함수를 완성해주세요.
k | dungeons | result |
---|---|---|
80 | [[80,20],[50,40],[30,10]] | 3 |
입출력 예 설명
현재 피로도는 80입니다.
만약, 첫 번째 → 두 번째 → 세 번째 던전 순서로 탐험한다면
만약, 첫 번째 → 세 번째 → 두 번째 던전 순서로 탐험한다면
따라서 이 경우 세 던전을 모두 탐험할 수 있으며, 유저가 탐험할 수 있는 최대 던전 수는 3입니다.
- 순열을 활용하여 모든 경우의 수를 만들어준다.
- 모든 경우를 순회한다.
2-1. 조건을 체크하며 최댓값을 구한다.- 최댓값 리턴
const Permutation = (arr, num) => { // 순열 구현
const result = [];
if (num === 1) return arr.map(v=>[v]);
arr.forEach((select, i, origin)=>{
const remainder = [...origin.slice(0,i),...origin.slice(i+1)];
const permutation = Permutation(remainder, num-1);
const combine = permutation.map(v=>[select, ...v]);
result.push(...combine);
});
return result;
}
const solution = (k, dungeons) => {
let answer = 0;
const d = Permutation(dungeons,dungeons.length);
d.forEach(v=>{
let copy_k = k;
let cnt = 0;
v.forEach((x,i)=>{
if (copy_k>=x[0]) { // 남은 피로도가 필요 피로도보다 크거나 같으면
copy_k-=x[1]; // 남은 피로도 - 소모 피로도
cnt++; // 던전 클리어 횟수 증가
}
})
answer = Math.max(answer, cnt); // 최댓값 구하기
})
return answer;
}
function solution(k, dungeons) {
const len = dungeons.length;
//모든 경우의 수를 확인하기 위한 배열
const visited = new Array(len).fill(false);
//클리어 횟수를 확인
let clearCnt = 0;
//모든 경우의 수를 확인하기 위한 재귀
const dfs = (k, curCnt) => {
//현재 클리어 횟수와 전의 클리어 횟수를 비교
clearCnt = Math.max(curCnt, clearCnt);
for(let i=0; i<len; i++) {
const [minK, useK] = dungeons[i];
//현재 피로도보다 크고 확인한적이 없다면
if(k >= minK && !visited[i]) {
//확인, 피로도 감소 및 카운트 증가 후 재귀
visited[i] = true;
dfs(k - useK, curCnt + 1);
visited[i] = false;
}
}
}
dfs(k, 0);
return clearCnt;
}
// 출처: https://velog.io/@duboo
순열을 활용한 완전탐색으로 풀었지만 DFS로도 풀 수 있던 것 같다.