[Algorithm] ํ๋ก๊ทธ๋๋จธ์ค - ํผ๋ก๋ / ๋ฐฑํธ๋ํน์ผ๋ก ๋ชจ๋ ๋ถ๋ถ์งํฉ ์ฐพ๊ธฐ
ํ๋ก๊ทธ๋๋จธ์ค ๋ ๋ฒจ 2 ํผ๋ก๋ ๋ฌธ์ ๋ ๋์ ๋ชฉ๋ก๊ณผ HP๊ฐ ์ฃผ์ด์ก์ ๋ ๋ฐฉ๋ฌธํ ์ ์๋ ์ต๋ ๋์ ์ ์๋ฅผ ๋ฐํํด์ผ ํ๋ค. ๊ฐ ๋์ ์ ์ต์ ํผ๋ก๋์ ์๋ชจ ํผ๋ก๋๋ฅผ ๊ฐ์ง๋ค. ์ต์ ํผ๋ก๋๋ ํด๋น ๋์ ์ ๋ฐฉ๋ฌธํ๊ธฐ ์ํด ํ์ํ ์ต์ HP๋ฅผ ์๋ฏธํ๊ณ , ์๋ชจ ํผ๋ก๋๋ ๋ง ๊ทธ๋๋ก ํด๋น ๋์ ์ ๋ฐฉ๋ฌธํ์ ๋ ์๋ชจ๋๋ HP๋ฅผ ๋ํ๋ธ๋ค. ๋ฌธ์ ์์ ์ฃผ์ด์ง๋ ๋งค๊ฐ๋ณ์๋ ์๋์ ๊ฐ๋ค.
k
: ์์ HP. e.g.,80
dungeons
: [์ต์ ํผ๋ก๋, ์๋ชจ ํผ๋ก๋]๋ก ์ด๋ฃจ์ด์ง ๋์ ๋ชฉ๋ก. e.g.,[[80,20],[50,40],[30,10]]
์ต์ ํผ๋ก๋์ ์๋ชจ ํผ๋ก๋๊ฐ ๊ฐ๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ๋ฐฉ๋ฌธ ์์์ ๋ฐ๋ผ ๋ฐฉ๋ฌธํ ์ ์๋ ๋์ ์ ์๊ฐ ๋ฌ๋ผ์ง๋ค. ์๋ฅผ ๋ค์ด [[80,20],[50,40],[30,10]]
๋์ ๋ชฉ๋ก์์ 2~3๋ฒ(i1~i2) ๋์ ๋ถํฐ ๋ฐฉ๋ฌธํ๋ฉด ์ต๋ 2๊ฐ ๋์ ๋ง ๋ฐฉ๋ฌธํ ์ ์๋ค. 1๋ฒ ๋์ (i0)์ ์ต์ ํผ๋ก๋๊ฐ 80์ด๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ๋์ ์ ๋จผ์ ๋ฐฉ๋ฌธํ๋ฉด HP๊ฐ 80 ๋ฏธ๋ง์ด ๋๊ณ ๊ทธ๋ผ 1๋ฒ ๋์ ์ ์ต์ ํผ๋ก๋๋ฅผ ๋ง์กฑํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ด๋ค.
- ์ฒซ ๋ฒ์งธ ๋์ ๋ถํฐ ๋ฐฉ๋ฌธํ์ ๋ : 1 → 2 → 3 (์ต๋ 3๊ฐ ๋์ )
- ๋ ๋ฒ์งธ ๋์ ๋ถํฐ ๋ฐฉ๋ฌธํ์ ๋ : 2 → 3 (์ต๋ 2๊ฐ ๋์ )
- ์ธ ๋ฒ์งธ ๋์ ๋ถํฐ ๋ฐฉ๋ฌธํ์ ๋ : 3 → 2 (์ต๋ 2๊ฐ ๋์ )
์์ด์ ์ด์ฉํ ๋ฐฉ๋ฒ
์ฃผ์ด์ง ๋์ ์ ๋ชจ๋ ๊ฐ๋ฅํ ์์๋ฅผ ํ์ํด๋ด์ผ ํ๋ฏ๋ก ๋์ ๋ชฉ๋ก์ ๋ํ ์์ด(Permutation)์ ์์ฑํ ๋ค, ๊ฐ ์์ด์ ์ํํ๋ฉด์ ๋ฐฉ๋ฌธํ ์ ์๋ ์ต๋ ๋์ ๊ฐ์๋ฅผ ๊ณ์ฐํ๋ ๋ฐฉ์์ผ๋ก ํด๊ฒฐํ๋ค.
const getPermutation = (arr, perm = [], max = 3) => {
if (perm.length === max) return [perm];
const result = [];
for (let i = 0; i < arr.length; i++) {
const newPerm = [...perm, arr[i]];
const rest = arr.slice(0, i).concat(arr.slice(i + 1));
result.push(...getPermutation(rest, newPerm, max));
}
return result;
};
function solution(k, dungeons) {
const perms = getPermutation(dungeons, [], dungeons.length);
let maxCount = 0;
for (const perm of perms) {
let currentK = k;
let count = 0;
for (const [requiredK, consumeK] of perm) {
if (currentK >= requiredK) {
currentK -= consumeK;
count++;
} else {
break;
}
}
maxCount = Math.max(count, maxCount);
}
return maxCount;
}
๋ชจ๋ ์์ด์ ๊ฐ์๋ $n!$ ์ด๋ฏ๋ก, getPermutation
ํจ์์ ์๊ฐ ๋ณต์ก๋๋ $O(n!)$ ์ด ๋๋ค. solution
ํจ์์์ ์์ฑํ ์์ด์ ๋ค์ ํ๋ฒ ์ํํ๋ฏ๋ก ์ ์ฒด ์ฝ๋์ ์๊ฐ ๋ณต์ก๋๋ $O(n! \cdot n)$์ผ๋ก ๋นํจ์จ์ ์ด๋ค. ๋ง์ฝ n์ด 10์ด๋ผ๋ฉด ์ฝ 3600๋ง ๋ฒ์ ์ฐ์ฐ์ด ํ์ํ๋ค.
๋ฐฑํธ๋ํน์ ์ด์ฉํ ๋ฐฉ๋ฒ
๐ก ๋ฐฑํธ๋ํน, ์์ด์ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ํ์ํ์ฌ ๋ต์ ์ฐพ๋ ์์ ํ์(Exhaustive Search)์ ์ํ๋ค.
๋ฐฑํธ๋ํน์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๊ฐ๋ฅํ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์๋ํ๋ฉด์, ์กฐ๊ฑด์ ๋ง์ง ์์ผ๋ฉด ํ์์ ์ค๋จํ๊ณ ์ด์ ๋จ๊ณ๋ก ๋์๊ฐ์ ๋ค๋ฅธ ๊ฐ๋ฅ์ฑ์ ํ์ํ๋ ๋ฐฉ๋ฒ์ด๋ค. ๊น์ด ์ฐ์ ํ์(DFS)๊ณผ ์ ์ฌํ์ง๋ง ๋ถํ์ํ ๊ฒฝ๋ก๋ฅผ ๋ฐฐ์ ํ๋ ๊ฐ์ง์น๊ธฐ(pruning) ๊ณผ์ ์ ํตํด ๋ฌธ์ ๋ฅผ ๋ ํจ์จ์ ์ผ๋ก ํด๊ฒฐํ๋ค.
ํ๋ก๊ทธ๋๋จธ์ค์์ ์ข์์๋ฅผ ๊ฐ์ฅ ๋ง์ด ๋ฐ์ ์ฝ๋๋ ๋ฐฑํธ๋ํน์ ์ด์ฉํด์ ํด๊ฒฐํ๋ค. ์ด ๋ฌธ์ ๋ ์์ด์ ๊ณ ๋ คํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์๊ฐ๋ณต์ก๋๋ ์ต์ ์ ๊ฒฝ์ฐ $O(n!)$์ด์ง๋ง ์ฝ๋๊ฐ ํจ์ฌ ๊น๋ํด์ง๋ค.
function solution(k, dungeons) {
const N = dungeons.length; // ๋์ ๊ฐ์
const visited = new Array(N).fill(false); // ๋ฐฉ๋ฌธ ์ฌ๋ถ๋ฅผ ์ถ์ ํ๋ ๋ฐฐ์ด
let maxCount = 0;
function dfs(hp, count) {
maxCount = Math.max(count, maxCount);
for (let i = 0; i < N; i++) {
// ์์ง ๋ฐฉ๋ฌธํ์ง ์์ ๋์ ์ด๊ณ , ๋์ ์ ์ต์ ํผ๋ก๋๋ฅผ ๋ง์กฑํ๋ฉด
if (hp >= dungeons[i][0] && !visited[i]) {
visited[i] = true; // ๋ฐฉ๋ฌธ ์ํ๋ก ๋ณ๊ฒฝ
dfs(hp - dungeons[i][1], count + 1);
visited[i] = false; // ๋ฏธ๋ฐฉ๋ฌธ ์ํ๋ก ๋ณ๊ฒฝ (๋ฐฑํธ๋ํน)
}
}
}
dfs(k, 0);
return maxCount;
}
์ ์ฝ๋์ ์๋ ๊ณผ์ ์ 4๋จ๊ณ๋ก ์ ๋ฆฌํ๋ฉด ์๋์ ๊ฐ๋ค.
- ์์ง ๋ฐฉ๋ฌธํ์ง ์์ ๋์ ์ด๊ณ , ๋์ ์ ์ต์ ํผ๋ก๋๋ฅผ ๋ง์กฑํ๋์ง ๊ฒ์ฌํ๋ค.
- ์กฐ๊ฑด์ ๋ง์กฑํ๋ฉด
count
,hp
์ํ๋ฅผ ์ ๋ฐ์ดํธํ๊ณ ๋์ ์ ๋ฐฉ๋ฌธํ๋ค. - ์ต๋ ๋ฐฉ๋ฌธ ์นด์ดํธ(maxCount)๋ฅผ ์ ๋ฐ์ดํธํ๋ค.
- ๋ฐฉ๋ฌธ ์ํ๋ฅผ ๋๋๋ฆฌ๊ณ (๋ฐฑํธ๋ํน), ๋ค์ ๋์ ์ ๋ฐฉ๋ฌธํ๋ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ค.
k = 80, dungeons = [[80, 20], [50, 40], [30, 10]]
N = 3 | visited = [f, f, f] | maxCount = 0
===================================================================
โด dfs(80, 0)
maxCount = max(0, 0) = 0
i0 -> โต dfs(80-20, 0+1) | visited = [t, f, f] -> visited = [f, f, f]
i1 -> โน dfs(80-40, 0+1) | visited = [f, t, f] -> visited = [f, f, f]
i2 -> โป dfs(80-10, 0+1) | visited = [f, f, t] -> visited = [f, f, f]
================================ i0 ================================
โต dfs(60, 1)
maxCount = max(1, 0) = 1
i0 -> pass(์ด๋ฏธ ๋ฐฉ๋ฌธ)
i1 -> โถ dfs(60-40, 1+1) | visited = [t, t, f] -> visited = [t, f, f]
i2 -> โท dfs(60-10, 1+1) | visited = [t, f, t] -> visited = [t, f, f]
โถ dfs(20, 2)
maxCount = max(2, 1) = 2
i0~i2 pass
โท dfs(50, 2)
maxCount = max(2, 2) = 2
i0 -> pass(์ด๋ฏธ ๋ฐฉ๋ฌธ)
i1 -> โธ dfs(50-40, 2+1) | visited = [t, t, t] -> visited = [t, f, t]
i2 -> pass(์ด๋ฏธ ๋ฐฉ๋ฌธ)
โธ dfs(10, 3)
maxCount = max(3, 2) = 3
i0~i2 pass
================================ i1 ================================
โน dfs(40, 1)
maxCount = max(1, 3) = 3
i0 -> pass(ํผ๋ก๋ ๋ง์กฑ ๋ชปํจ)
i1 -> pass(์ด๋ฏธ ๋ฐฉ๋ฌธ)
i2 -> โบ dfs(40-10, 1+1) | visited = [f, t, t] -> visited = [f, t, f]
โบ dfs(30, 2)
maxCount = max(2, 3) = 3
i0~i2 pass
================================ i2 ================================
โป dfs(70, 1)
maxCount = max(1, 3) = 3
i0 -> pass(ํผ๋ก๋ ๋ง์กฑ ๋ชปํจ)
i1 -> โผ dfs(70-40, 1+1) | visited = [f, t, t] -> visited = [f, f, t]
i2 -> pass(์ด๋ฏธ ๋ฐฉ๋ฌธ)
โผ dfs(30, 2)
maxCount = max(1, 3) = 3
i0~i2 pass
(๋ฒ์ธ) ๋ถ๋ถ์งํฉ ์ฐพ๊ธฐ
๋ถ๋ถ์งํฉ์ ์ด๋ค ์งํฉ์ ์์๋ค ์ค ์ผ๋ถ ๋๋ ์ ์ฒด๋ฅผ ํฌํจํ๋ ์งํฉ์ ์๋ฏธํ๋ค. ์งํฉ A์ ๋ชจ๋ ์์๊ฐ ์งํฉ B์ ํฌํจ๋์ด ์๋ค๋ฉด, ์งํฉ A๋ ์งํฉ B์ ๋ถ๋ถ์งํฉ(Subset)์ด ๋๋ฉฐ, ๊ธฐํธ๋ $A \subset B$๋ก ๋ํ๋ธ๋ค.
๋ถ๋ถ์งํฉ์ ์์ ๊ฐ์ 0๊ฐ๋ถํฐ ์ต๋ ์์ ๊ฐ์๊น์ง ํฌํจํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ณต์งํฉ๊ณผ ์๊ธฐ ์์ ๋ ๋ถ๋ถ์งํฉ์ ํฌํจ๋๋ค. ์๋ฅผ ๋ค์ด ์งํฉ {1, 2, 3, 4}์ ๋ถ๋ถ ์งํฉ์ ์๋์ ๊ฐ๋ค.
- ์์์ ๊ฐ์๊ฐ 0๊ฐ์ธ ๋ถ๋ถ์งํฉ: ๊ณต์งํฉ $\emptyset$
- ์์์ ๊ฐ์๊ฐ 1๊ฐ์ธ ๋ถ๋ถ์งํฉ(1์๋ฆฌ ์กฐํฉ): {1}, {2}, {3}, {4}
- ์์์ ๊ฐ์๊ฐ 2๊ฐ์ธ ๋ถ๋ถ์งํฉ(2์๋ฆฌ ์กฐํฉ): {1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 4}
- ์์์ ๊ฐ์๊ฐ 3๊ฐ์ธ ๋ถ๋ถ์งํฉ(3์๋ฆฌ ์กฐํฉ): {1, 2, 3}, {1, 2, 4}, {1, 3, 4}, {2, 3, 4}
- ์์์ ๊ฐ์๊ฐ 4๊ฐ์ธ ๋ถ๋ถ์งํฉ(์๊ธฐ ์์ , 4์๋ฆฌ ์กฐํฉ): {1, 2, 3, 4}
๊ฐ ์์๋ ๋ถ๋ถ์งํฉ์ ํฌํจ๋๊ฑฐ๋ ํฌํจ๋์ง ์๋ ๋ ๊ฐ์ง ์ ํ์ ๊ฐ์ง๋ฏ๋ก, n๊ฐ ์์์ ๋ํ ๋ถ๋ถ์งํฉ์ ์ด๊ฐ์๋ $2 \times 2 \times \dots \times 2 = 2^n$๊ฐ๊ฐ ๋๋ค.
์ด์ฒ๋ผ ๋ถ๋ถ์งํฉ์ ์ฃผ์ด์ง ์งํฉ์ ์์๋ค๋ก ๋ง๋ค ์ ์๋ ๋ชจ๋ ๊ฐ๋ฅํ ์กฐํฉ(Combination)์ ์๋ฏธํ๊ธฐ๋ ํ๋ค. ํํธ, ํน์ ์งํฉ์ ๋ชจ๋ ๋ถ๋ถ์งํฉ์ ์ฐพ์ ๋๋ ๋ฐฑํธ๋ํน์ ์ฌ์ฉํ ์ ์๋ค. ์๊ฐ๋ณต์ก๋๋ ๋ถ๋ถ์งํฉ์ ์ด๊ฐ์์ ๋์ผํ $O(2^n)$์ด ๋๋ค.
function findSubsets(nums) {
const result = [];
function generateSubsets(start, path) {
result.push([...path]); // ํ์ฌ ๊ฒฝ๋ก๋ฅผ ๊ฒฐ๊ณผ์ ์ถ๊ฐ
for (let i = start; i < nums.length; i++) {
path.push(nums[i]); // ํ์ฌ ์์๋ฅผ ๊ฒฝ๋ก์ ์ถ๊ฐ
generateSubsets(i + 1, path); // ๋ค์ ์์ ํ์
path.pop(); // ๊ฒฝ๋ก์์ ๋ง์ง๋ง ์์ ์ ๊ฑฐ(๋ฐฑํธ๋ํน)
}
}
generateSubsets(0, []);
return result;
}
- ํ์ฌ ๊ฒฝ๋ก์ ๋ณต์ฌ๋ณธ์
result
์ ์ถ๊ฐํ๋ค start
์ธ๋ฑ์ค์ ์๋ ์์๋ถํฐpath
์ ์ถ๊ฐํ์ฌ ๋ค์ ์์๋ฅผ ํ์ํ๋ค- ํ์์ ๋ง์น๋ฉด ๋ง์ง๋ง ์์๋ฅผ
path
์์ ์ ๊ฑฐํ๋ค(๋ฐฑํธ๋ํน) nums
๋ฐฐ์ด์ ๋ง์ง๋ง ์ธ๋ฑ์ค๊น์ง ์ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ค.
nums = [1, 2, 3]
==============================================================
f(0, [])
result = [[]]
i0 -> path = [1] -> โด f(0+1, [1]) -> path = []
i1 -> path = [2] -> โธ f(1+1, [2]) -> path = []
i2 -> path = [3] -> โบ f(2+1, [3]) -> path = []
โด f(1, [1])
result = [[], [1]]
i1 -> path = [1, 2] -> โต f(1+1, [1, 2]) -> path = [1]
i2 -> path = [1, 3] -> โท f(2+1, [1, 3]) -> path = [1]
โต f(2, [1, 2])
result = [[], [1], [1, 2]]
i2 -> path = [1, 2, 3] -> โถ f(2+1, [1, 2, 3]) -> path = [1, 2]
โถ f(3, [1, 2, 3])
result = [[], [1], [1, 2], [1, 2, 3]]
skip loop
โท f(3, [1, 3])
result = [[], [1], [1, 2], [1, 2, 3], [1, 3]]
skip loop
โธ f(2, [2])
result = [[], [1], [1, 2], [1, 2, 3], [1, 3], [2]]
i2 -> path = [2, 3] -> โน f(2+1, [2, 3]) -> path = [2]
โน f(3, [2, 3])
result = [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3]]
skip loop
โบ f(3, [3])
result = [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
skip loop
๊ธ ์์ ์ฌํญ์ ๋ ธ์ ํ์ด์ง์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ๋ฐ์๋ฉ๋๋ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด ์ฃผ์ธ์
'๐ช Programming' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
[Dart] ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์์ ๋คํธ ํ์ต - Part 2
[Dart] ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์์ ๋คํธ ํ์ต - Part 2
2024.08.21 -
[Dart] ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์์ ๋คํธ ํ์ต - Part 1
[Dart] ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ์์ ๋คํธ ํ์ต - Part 1
2024.08.21 -
[DevTools] ๋ฆฌ์กํธ ํ ์คํธ ํ๊ฒฝ(Vitest, React Testing Library) ๋ฐ CI ๊ตฌ์ถ
[DevTools] ๋ฆฌ์กํธ ํ ์คํธ ํ๊ฒฝ(Vitest, React Testing Library) ๋ฐ CI ๊ตฌ์ถ
2024.07.22 -
[JS] ์๋ฐ์คํฌ๋ฆฝํธ ์ ๊ท์์ผ๋ก ์ฒ ๋จ์ ๊ตฌ๋ถ์ ์ถ๊ฐํ๊ธฐ (๋จ์ด ๊ฒฝ๊ณ, ์ ํ๋ฐฉํ์)
[JS] ์๋ฐ์คํฌ๋ฆฝํธ ์ ๊ท์์ผ๋ก ์ฒ ๋จ์ ๊ตฌ๋ถ์ ์ถ๊ฐํ๊ธฐ (๋จ์ด ๊ฒฝ๊ณ, ์ ํ๋ฐฉํ์)
2024.07.18