Table of Contents
์๊ณ ๋ฆฌ์ฆ์ ์์ ํ์(Brute-Force, ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ํ์ํด๋ณด๋ ๊ฒ)์์ ์์ํ๋ค. ์ด๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๋ค ๋ฐ์ ธ๋ณด๊ธฐ ๋๋ฌธ์ ๊ฐ๋ ฅํ์ง๋ง, ์ต๋์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ์ง๊ฒ ๋๋ค. ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์๊ฐํด๋ณด๊ณ ๋ํ ์๊ฐ๋ณต์ก๋๋ฅผ ์ค์ผ ์ ์๋ ๋ถ๋ถ์ด ์๋ค๋ฉด ๊ทธ๋ฌํ ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐํด๋ณด๊ณ ๊ทธ ์๊ณ ๋ฆฌ์ฆ์ ์ ํํ๊ฒ ์ฝ๋๋ก ๊ตฌํํ ์ ์์ด์ผ ํ๋ค. ์ข์ ์ฝ๋๋ฅผ ์ง๊ธฐ ์ํด์๋ ๋ค์ ๊ณผ์ ์ ์ฐ์ต์ด ํ์ํ๋ค.
- ๋ฌธ์ ๋ฅผ ํ์ ํ๊ณ ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐํ๊ธฐ
- ์๊ณ ๋ฆฌ์ฆ์ ๊ณต๊ฐ๋ณต์ก๋์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ณ์ฐํ์ฌ ๋ฌธ์ ์ ์ ์ฝ ์กฐ๊ฑด ๋ด์ ์ํ๋ ์ ์๋ ์๊ณ ๋ฆฌ์ฆ์ธ์ง ํ๋จํ๊ธฐ
- ์๊ณ ๋ฆฌ์ฆ์ ๋น ๋ฅด๊ณ ์ ํํ๊ฒ ๊ตฌํํ๊ธฐ (์ฐ์ต๋ง์ด ์ ๋ต)
๋ณต์ก๋๋ ์๊ณ ๋ฆฌ์ฆ์ ์ฑ๋ฅ์ ๋ํ๋ด๋ ์ฒ๋์ด๋ค.
๋ณต์ก๋๋ ์๊ฐ ๋ณต์ก๋(Time Complexity) ์ ๊ณต๊ฐ ๋ณต์ก๋(Space Complexity) ๋ก ๋๋ ์ ์๋ค.
์๊ฐ ๋ณต์ก๋๋ ํน์ ํ ํฌ๊ธฐ์ ์
๋ ฅ์ ๋ํ์ฌ ์๊ณ ๋ฆฌ์ฆ์ด ์ผ๋ง๋ ์ค๋ ๊ฑธ๋ฆฌ๋์ง๋ฅผ ์๋ฏธํ๊ณ ๊ณต๊ฐ ๋ณต์ก๋๋ ํน์ ํ ํฌ๊ธฐ์ ์
๋ ฅ์ ๋ํ์ฌ ์๊ณ ๋ฆฌ์ฆ์ด ์ผ๋ง๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐจ์งํ๋์ง๋ฅผ ์๋ฏธํ๋ค.
๋์ผํ ๊ธฐ๋ฅ์ ์ํํ๋ ์๊ณ ๋ฆฌ์ฆ์ด ์๋ค๋ฉด ์ผ๋ฐ์ ์ผ๋ก ๋ณต์ก๋๊ฐ ๋ฎ์์๋ก ์ข์ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
๋ณต์ก๋์ ์ธก์ ์ผ๋ก ์ฐ๋ฆฌ๋ '์๊ณ ๋ฆฌ์ฆ์ ์ํด ํ์ํ ์ฐ์ฐ์ ํ์'๋ก ์๊ฐ ๋ณต์ก๋๋ฅผ ๊ณ์ฐํ ์ ์๊ณ '์๊ณ ๋ฆฌ์ฆ์ ์ํด ํ์ํ ๋ฉ๋ชจ๋ฆฌ์ ์'์ผ๋ก ๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ๊ณ์ฐํ ์ ์๋ค.
๋ณดํต ์๊ฐ ๋ณต์ก๋๋ฅผ ํํํ ๋๋ Big-O ํ๊ธฐ๋ฒ(Big-O notation)์ ์ฌ์ฉํ๋ค. ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ์ฆ๊ฐํ๋ ํญ๋ง ๊ณ ๋ คํ๋ ํ๊ธฐ๋ฒ์ผ๋ก limit์ ๋ํ๋ธ๋ค.
์๋ฅผ ๋ค์ด N๊ฐ์ ๋ฐ์ดํฐ๊ฐ ์์ ๋ ๋ชจ๋ ๋ฐ์ดํฐ์ ๊ฐ์ ๋ํ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ ํ๋ก๊ทธ๋จ์ด๋ผ๋ฉด N๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ฐจ๋ก๋ก Nํ ๋ํด์ค๋ค. ์ด ๋ ์ฐ์ฐ ํ์๋ N์ ๋น๋กํ๊ณ ์๋ก์ด ๋ณ์๋ฅผ ๋ง๋ค๊ฑฐ๋ ์ถ๋ ฅํ๋ ์ฐ์ฐ์ ์๋์ ์ผ๋ก N์ด ์ปค์ง๋ค๋ฉด ๋ฌด์ํ ์ ์๊ฒ ๋๋ค. ๊ฐ์ฅ ์ํฅ๋ ฅ์ด ํฐ ๋ถ๋ถ์ด N์ผ๋ก ์๊ฐ ๋ณต์ก๋๋ฅผ O(N)์ผ๋ก ํ์ํ๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ฝ๋ฉํ
์คํธ์์๋ ์ต์
์ ๊ฒฝ์ฐ์ ๋ํ ์ฐ์ฐ ํ์๊ฐ ๊ฐ์ฅ ์ค์ํ๋ฏ๋ก ์์ ์ด ์์ฑํ ์์ค์ฝ๋๋ฅผ ์ ํํ ์ดํดํ๊ณ ๋ถ์ํ์ฌ ์ต์
์ ๊ฒฝ์ฐ์ ์๊ฐ ๋ณต์ก๋๋ฅผ ๊ณ์ฐํด์ผ ํ๋ค.
O(N3)์ ๋์ด๊ฐ๋ฉด ๋ฌธ์ ํ์ด์์ ์ฌ์ฉํ๊ธฐ ์ด๋ ค์ด ์๊ณ ๋ฆฌ์ฆ์ผ๋ก N์ด 1000๊ฐ๋ฅผ ๋์ด๊ฐ๋ฉด 5์ด ์ด์์ ์๊ฐ์ด ์์๋ ๊ฒ์ด๋ผ๊ณ ์์ํ ์ ์๋ค.
- N์ ๋ฒ์๊ฐ 500์ธ ๊ฒฝ์ฐ) ์๊ฐ ๋ณต์ก๋๊ฐ O(N3)์ธ ์๊ณ ๋ฆฌ์ฆ์ ์ค๊ณํ๋ฉด ๋ฌธ์ ํด๊ฒฐ ๊ฐ๋ฅ
- N์ ๋ฒ์๊ฐ 2000์ธ ๊ฒฝ์ฐ) ์๊ฐ ๋ณต์ก๋๊ฐ O(N2)์ธ ์๊ณ ๋ฆฌ์ฆ์ ์ค๊ณํ๋ฉด ๋ฌธ์ ํด๊ฒฐ ๊ฐ๋ฅ
- N์ ๋ฒ์๊ฐ 100,000์ธ ๊ฒฝ์ฐ) ์๊ฐ ๋ณต์ก๋๊ฐ O(Nlog N)์ธ ์๊ณ ๋ฆฌ์ฆ์ ์ค๊ณํ๋ฉด ๋ฌธ์ ํด๊ฒฐ ๊ฐ๋ฅ
- N์ ๋ฒ์๊ฐ 10,000,000์ธ ๊ฒฝ์ฐ) ์๊ฐ ๋ณต์ก๋๊ฐ O(N)์ธ ์๊ณ ๋ฆฌ์ฆ์ ์ค๊ณํ๋ฉด ๋ฌธ์ ํด๊ฒฐ ๊ฐ๋ฅ
๋ณดํต 1์ต(108)๋ฒ์ ์ฐ์ฐ๋น 1์ด์ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค๊ณ ๊ฐ์ฃผํ๋ค.
๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ํ๊ธฐํ ๋์๋ Big-O ํ๊ธฐ๋ฒ(Big-O notation)์ ์ฌ์ฉํ๋ค.
์ฝ๋ฉ ํ
์คํธ์์๋ ๋ณดํต ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ 128~512MB๋ก ์ ํํ๊ณ ์๋ค. ์ฆ ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ ๋ฐ์ดํฐ์ ๊ฐ์๊ฐ 1,000๋ง ๋จ์๋ฅผ ๋์ด๊ฐ์ง ์๋๋ก ์๊ณ ๋ฆฌ์ฆ ์ค๊ณ๋ฅผ ํด์ผํ๊ณ 100๋ง ๊ฐ ์ด์์ ๋ฐ์ดํฐ๊ฐ ๋ค์ด๊ฐ ์ ์๋ ํฌ๊ธฐ์ ๋ฐฐ์ด์ ์ ์ธํ๋ ๊ฒฝ์ฐ๋ ๊ฑฐ์ ๋๋ฌผ๋ค.
๋ฆฌ์คํธ์ ํฌ๊ธฐ๊ฐ 1,000๋ง ๋จ์ ์ด์์ด๋ผ๋ฉด ์์ ์ด ์๊ณ ๋ฆฌ์ฆ์ ์๋ชป ์ค๊ณํ ๊ฒ์ด ์๋์ง ํ์ธํ๋ ๊ณผ์ ์ด ํ์ํ๋ค.
์ผ๋ฐ์ ์ผ๋ก ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ํ์ด์์์ ๋ณต์ก๋๋ ์๊ฐ ๋ณต์ก๋๋ฅผ ์๋ฏธํ๋ค.
์คํฐ๋ ์๋ฃ - ์์ฑ์ ๊ถํ์ง | ๊น์ด์ฐ์ ํ์ DFS ์ ๋ํ์ฌ
- ํ ๊ฒฝ๋ก๋ก ์ต๋ํ ๊น์ํ๊ฒ ๋ค์ด๊ฐ์ ํ์ํ ํ ๋ค์ ๋์๊ฐ ๋ค๋ฅธ ๊ฒฝ๋ก๋ก ํ์ํ๋ ๋ฐฉ์
- ์ฌ๊ทํจ์, Stack์ ์ด์ฉํด ๊ตฌํ
- ์ ์ํ ์ : Stack Overflow (๊ธฐ์ ์กฐ๊ฑด ์ ์ค์ )
- ํ์ฉ : ๋ฐฑํธ๋ํน, ๋จ์ ์ /๋จ์ ์ ์ฐพ๊ธฐ, ์์์ ๋ ฌ, ์ฌ์ดํด ์ฐพ๊ธฐ ๋ฑ
void dfs(int current) {
if (current == target) { // ๋ชฉ์ ์ง์ธ๊ฐ?
System.out.println("๋ชฉ์ ์ง์
๋๋ค.");
return;
}
visited[current] = true; // ์ฒดํฌ์ธ
for (int next : graph[current]) { // ๊ฐ ์ ์๋ ๊ณณ์ ์ํ
if (!visited[next]) { // ๊ฐ ์ ์๋๊ฐ?
dfs(next); // ๊ฐ๋ค
}
}
visited[current] = false; // ์ฒดํฌ์์
}
- ์์ ๋ ธ๋์์ ์์ํ์ฌ ์ธ์ ํ ๋ ธ๋๋ฅผ ๋จผ์ ํ์ํ๋ ๋ฐฉ์, ์ฌ๋ฌ ๊ฒฝ๋ก ๋์์ ํ์ ๊ฐ๋ฅ
- Queue๋ฅผ ์ด์ฉํด ๊ตฌํ
- ์ ์ํ ์ : ๋ฉ๋ชจ๋ฆฌ ์ด๊ณผ (๋ฐฉ๋ฌธ ์ฒดํฌ ๊ผญ ํด์ค์ผ ํจ)
- ํ์ฉ : ์ต๋จ๊ฒฝ๋ก ์ฐพ๊ธฐ, ์์์ ๋ ฌ ๋ฑ
void bfs(int start) {
Queue<Integer> q = new LinkedList<>();
q.offer(start);
visited[start] = true;
while (!q.isEmpty()) {
int current = q.poll(); // ํ์์ ๊บผ๋ธ๋ค
if (current == target) { // ๋ชฉ์ ์ง์ธ๊ฐ?
System.out.println("๋ชฉ์ ์ง์
๋๋ค.");
return;
}
for (int next : graph[current]) { // ๊ฐ ์ ์๋ ๊ณณ์ ์ํ
if (!visited[next]) { // ๊ฐ ์ ์๋๊ฐ?
visited[next] = true; // ์ฒดํฌ์ธ
q.offer(next); // ํ์ ๋ฃ๋๋ค
}
}
}
}
- ์๋ก ๋ค๋ฅธ ๊ฒ๋ค ์ค ๋ช ๊ฐ๋ฅผ ๋ฝ์์ ํ ์ค๋ก ๋์ดํ๋ ๊ฒ
- ์๋ก ๋ค๋ฅธ n๊ฐ ์ค r๊ฐ๋ฅผ ํํ๋ ์์ด
nPr = n * (n-1) * (n-2) * ... * (n-r+1)
nPn = n!
์ด๋ฉฐ10!
์ด์์ ๊ณ์ฐ์ ์ํํ๋ค.
public class PermutationTest {
static int N;
static int[] input, result;
static boolean[] isSelected;
public static void main(String[] args) {
N = 5; // N ์ด๊ธฐํ
input = new int[N]; // ์
๋ ฅ ๋ฐ์ ์ซ์ ๋ฐฐ์ด
result = new int[N]; // ์์ด ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ ๋ฐฐ์ด
isSelected = new boolean[N]; // ์ ํ ์ ๋ณด๋ฅผ ๊ด๋ฆฌํ ๋ฐฐ์ด
for (int i = 0; i < N; i++) {
input[i] = i; // input ๋ฐฐ์ด ์ด๊ธฐํ
}
System.out.println("Permutation Recursive");
recursive(0);
System.out.println("Permutation Bitmask");
bitmask(0, 0);
System.out.println("Permutation Next Permutation");
Arrays.sort(input); // ์ค๋ฆ์ฐจ์ ์ ๋ ฌํ์ฌ ๊ฐ์ฅ ์์ ์์ด์ ํํ๋ก ๋ง๋ฆ
do {
System.out.println(Arrays.toString(input));
} while (np());
}
// ์ฌ๊ท ํจ์
private static void recursive(int cnt) {
if (cnt == N) {
System.out.println(Arrays.toString(result));
return;
}
for (int i = 0; i < N; i++) {
if (isSelected[i]) continue;
result[cnt] = input[i];
isSelected[i] = true;
recursive(cnt+1);
isSelected[i] = false;
}
}
// ๋นํธ๋ง์คํฌ
private static void bitmask(int cnt, int flag) {
if (cnt == N) {
System.out.println(Arrays.toString(result));
return;
}
for (int i = 0; i < N; i++) {
if ((flag & 1<<i) != 0) continue;
result[cnt] = input[i];
bitmask(cnt+1, flag | 1<<i);
}
}
// next permutation
private static boolean np() {
int i = N-1;
while (i > 0 && input[i-1] >= input[i]) --i;
// ๋์ด์ ์์๋ฆฌ๊ฐ ์๋ ์ํฉ : ํ ์์ด์ ์ํ๊ฐ ๊ฐ์ฅ ํฐ ์์ด (๋ง์ง๋ง ์์ด)
if (i == 0) return false;
int j = N-1;
while (input[i-1] >= input[j]) --j; // i-1๋ณด๋ค ํฐ ๊ฐ์ ๋ฌด์กฐ๊ฑด ์์ (์ ์ด๋ i)
swap(i-1, j);
int k = N-1;
while (i < k) {
swap(i++, k--);
}
return true;
}
private static void swap(int i, int j) {
int temp = input[i];
input[i] = input[j];
input[j] = temp;
}
}
- ์๋ก ๋ค๋ฅธ n๊ฐ์ ์์ ์ค r๊ฐ๋ฅผ ์์ ์์ด ๊ณจ๋ผ๋ธ ๊ฒ
- ์๋ก ๋ค๋ฅธ n๊ฐ ์ค r๊ฐ๋ฅผ ํํ๋ ์กฐํฉ
nCr = n! / (n-r)!r!
public class CombinationTest {
static int N, R;
static int[] input, result, P;
public static void main(String[] args) {
N = 5; // N ์ด๊ธฐํ
R = 3;
input = new int[N]; // ์
๋ ฅ ๋ฐ์ ์ซ์ ๋ฐฐ์ด
result = new int[R]; // ์กฐํฉ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ ๋ฐฐ์ด
for (int i = 0; i < N; i++) {
input[i] = i; // input ๋ฐฐ์ด ์ด๊ธฐํ
}
System.out.println("Combination Recursive");
recursive(0, 0);
System.out.println("Combination Next Permutation");
P = new int[N]; // N ํฌ๊ธฐ์ flag ๋ฐฐ์ด
// ์์ ํฌ๊ธฐ์ ๊ฐ์ ํฌ๊ธฐ์ int ๋ฐฐ์ด P๋ฅผ ์์ฑํ์ฌ ๋ค์์ r๊ฐ๋ฅผ 1๋ก ์ด๊ธฐํ
int cnt = 0;
while (++cnt <= R) P[N-cnt] = 1;
do {
for (int i = 0; i < N; i++) {
// P ๋ฐฐ์ด์์ 0์ด ์๋ ๊ฐ์ ๊ฐ๊ณ ์๋ ์์น์ ํด๋นํ๋ ์์๊ฐ ์กฐํฉ์ ์ ํ๋ ๊ฒ
if (P[i] == 1) System.out.print(input[i] + " ");
}
System.out.println();
} while (np());
}
private static void recursive(int cnt, int start) {
if (cnt == R) {
System.out.println(Arrays.toString(result));
return;
}
for (int i = start; i < N; i++) {
result[cnt] = input[i];
recursive(cnt+1, i+1);
}
}
private static boolean np() {
// STEP 1
int i = N-1;
while (i > 0 && P[i-1] >= P[i]) --i;
if (i == 0) return false;
// STEP 2
int j = N-1;
while (P[i-1] >= P[j]) --j;
// STEP 3
swap(i-1, j);
// STEP 4
int k = N-1;
while (i < k) {
swap(i++, k--);
}
return true;
}
private static void swap(int i, int j) {
int temp = P[i];
P[i] = P[j];
P[j] = temp;
}
}
- ์งํฉ์ ํฌํจ๋ ์์๋ค์ ์ ํํ๋ ๊ฒ
- ์งํฉ์ ์์๊ฐ n๊ฐ์ผ ๋, ๊ณต์งํฉ์ ํฌํจํ ๋ถ๋ถ์งํฉ(๋ฉฑ์งํฉ, power set)์ ๊ฐ์๋ 2N๊ฐ์ด๋ค. (๊ฐ ์์๋ฅผ ํฌํจ์ํค๊ฑฐ๋ / ํฌํจ์ํค์ง ์๊ฑฐ๋)
public class SubsetTest {
static int N;
static int[] input;
static boolean[] isSelected;
public static void main(String[] args) {
N = 3; // N ์ด๊ธฐํ
input = new int[N]; // ์
๋ ฅ ๋ฐ์ ์ซ์ ๋ฐฐ์ด
isSelected = new boolean[N]; // ์ ํ ์ ๋ณด๋ฅผ ๊ด๋ฆฌํ ๋ฐฐ์ด
for (int i = 0; i < N; i++) {
input[i] = i; // input ๋ฐฐ์ด ์ด๊ธฐํ
}
System.out.println("Subset Recursive");
recursive(0);
System.out.println("Subset Binary Counting");
binaryCounting(1<<N); // 2^N
}
private static void recursive(int cnt) {
if (cnt == N) {
for (int i = 0; i < N; i++) {
System.out.print( (isSelected[i] ? input[i] : "X") + " ");
}
System.out.println();
return;
}
// ์ ํ
isSelected[cnt] = true;
recursive(cnt+1);
// ๋น์ ํ
isSelected[cnt] = false;
recursive(cnt+1);
}
private static void binaryCounting(int caseCount) {
for (int flag = 0; flag < caseCount; flag++) { // flag : ๋นํธ๋ง์คํฌ๋์ด ์๋ ์
for (int j = 0; j < N; j++) {
if ((flag & 1<<j) != 0) {
System.out.print(input[j] + " ");
} else {
System.out.print("X ");
}
}
System.out.println();
}
}
}
๋ฐฑํธ๋ํน์ DFS ๋ฌธ์ ์์ ๋ชจ๋ ๋ ธ๋๋ฅผ ํ์ํ ํ์๊ฐ ์์ ๊ฒฝ์ฐ ์ ์ฉํ๋ค. ๋ค์ ๋งํด, ๋ฃจํธ ๋ ธ๋์์ ๋ฆฌํ ๋ ธ๋๊น์ง์ ๊ฒฝ๋ก๋ ํด๋ต ํ๋ณด(candidate solution)๊ฐ ๋๋๋ฐ ์ด ๋ ๋ชจ๋ ํ๋ณด๋ฅผ ๊ฒ์ฌํ์ง ์๊ณ ํ๋ณด๊ฐ ์๋๋ผ๊ณ ํ๋จ๋๋ฉด ๋ ์ด์ ๊ฒ์ํ์ง ์๋๋ค.
- ์ ๋ง(promising)ํ๋ค : ์ด๋ค ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธํ์์ ๋ ๊ทธ ๋ ธ๋๋ฅผ ํฌํจํ ๊ฒฝ๋ก๊ฐ ํด๋ต์ด ๋ ์ ์๋ค.
- ๊ฐ์ง์น๊ธฐ(pruning) : ์ ๋งํ์ง ์์ ๋ ธ๋๊ฐ ํฌํจ๋๋ ๊ฒฝ๋ก๋ ๋ ์ด์ ๊ณ ๋ คํ์ง ์๋๋ค.
- ์ํ ๊ณต๊ฐ ํธ๋ฆฌ์ ๊น์ด ์ฐ์ ํ์(DFS)์ ์ค์ํ๋ค.
- ๊ฐ ๋ ธ๋๊ฐ ์ ๋ง(promising)ํ์ง๋ฅผ ์ ๊ฒํ๋ค.
- ๋ง์ผ ๊ทธ ๋ ธ๋๊ฐ ์ ๋ง(promising)ํ์ง ์์ผ๋ฉด, ๊ทธ ๋ ธ๋์ ๋ถ๋ชจ๋ก ๋๋์๊ฐ(backtracking) ๋ค์ ์์ ๋ ธ๋๋ก์ ๊ฒ์์ ๊ณ์ํ๋ค.
๋ฐฑํธ๋ํน์ ์ฌ์ฉํ๋ฉด ๊ฐ์ง์น๊ธฐ(pruning) ๋ฅผ ํตํด ๋ถํ์ํ ๊ฒฝ๋ก๋ฅผ ์ฐจ๋จํ์ฌ ์์ ํ์(DFS)๋ณด๋ค ๊ฒฝ์ฐ์ ์๋ฅผ ํจ์ฌ ์ค์ผ ์ ์๋ค. ๋ํ์ ์ผ๋ก N-Queen ๋ฌธ์ ๊ฐ ๋ฐฑํธ๋ํน์ ์ข์ ์์์ด๋ค.
N-Queen ๋ฌธ์ ๋ N*N ์ฒด์คํ์ ํธ N๊ฐ๋ฅผ ์๋ก ๊ณต๊ฒฉํ ์ ์๊ฒ ๋๋ ๋ฌธ์ ๋ฅผ ๋งํ๋ค. ๋ฐฑํธ๋ํน ์๊ณ ๋ฆฌ์ฆ์ด N-Queen์ ํด๊ฒฐํ๋ ๊ฐ์ฅ ๋ํ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
BOJ 9663 ๋ฌธ์ ๋ฅผ ์์๋ก ๋ค์ด ์ค๋ช ์ ํด๋ณด๊ฒ ๋ค.
์๋ก ๊ณต๊ฒฉํ ์ ์๋๋ก ํธ์ ๋๋ ๋ฐฉ๋ฒ์ ์๋ฅผ ๊ตฌํ๋ ๋ฌธ์ ์ด๋ค.
์์ ๊ฐ์ด ๋ฐฐ์นํ๋ ๋ฐฉ๋ฒ์ด ์ ๋ต์ด ๋๋ค.
๋ฐฑํธ๋ํน์ ์ฌ์ฉํ์ง ์๊ณ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด N๊ฐ์ ํธ์ ๋์ ์ ์๋ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์๋ํด๋ณธ ๋ค ์กฐ๊ฑด์ ๋ถํฉํ๋ ์ง๋ฅผ ์ฒดํฌํด๋ณด๋ฉด ๋๋ค.
ํ์ง๋ง ์ด๋ฌํ ์์ ํ์ ๋ฐฉ์์ ์์ฒญ๋๊ฒ ํฐ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ฐ๋๋ค.
๋ชจ๋ ๋
ธ๋์ ํธ์ ๋์๋ณด๋ ๊ฒฝ์ฐ์ ์ n*nCn
, ๋๊ฐ์ /์์ง/์ํ์ ํธ์ด ์๋์ง ํ๋จํ๋๋ฐ O(N^2)
์ด๋ ์๊ฐ๋ณต์ก๋๊ฐ ํฐ๋ฌด๋ ์์ด ์ปค์ง์ ์ ์ ์๋ค.
n๊ฐ์ด
10
๋ง ๋์ด๋ 17,310,309,456,440 ๊ฐ์ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ฐ๋๋ค.
N์ด ์ปค์ง์๋ก ์๊ฐ๋ณต์ก๋ ์ญ์ ๊ธฐํ๊ธ์์ ์ผ๋ก ์ฆ๊ฐํ๋ฏ๋ก ๋๋ฌด๋ ๋นํจ์จ์ ์ด๋ค.
์ด๋ฅผ ํจ์จ์ ์ผ๋ก ํด๊ฒฐํ๊ธฐ ์ํด ๋ฐฑํธ๋ํน ์๊ณ ๋ฆฌ์ฆ
์ ์ฌ์ฉํ๋ค.
๋จผ์ ํธ์ ํน์ฑ์ ์๊ฐํด๋ณด์.
- ํธ์ ์์ง์ ์์ ์๋ ๋ง์ ๊ณต๊ฒฉํ ์ ์๋ค.
- ํธ์ ์ํ์ ์์ ์๋ ๋ง์ ๊ณต๊ฒฉํ ์ ์๋ค.
- ํธ์ ๋๊ฐ์ ์์ ์๋ ๋ง์ ๊ณต๊ฒฉํ ์ ์๋ค.
์ด ํน์ฑ์ ํตํด ์ฐ๋ฆฌ๋ ํธ์ ๋์ ์ ์๋ ์๋ฆฌ์ ๋ํด ํ๋จํ ์ ์๋ค.
- ํธ์ ํ row์ ํ๋๋ง ๋ ์ ์๋ค.
- ํธ์ ํ column์ ํ๋๋ง ๋ ์ ์๋ค.
- ๋๊ฐ์ ์ ํธ์ด ์๋ค๋ฉด ๋ ์ ์๋ค.
์ด ๊ณผ์ ์ด ์ ๋ง์ฑ ํ๋จ
๊ณผ ๊ฐ์ง์น๊ธฐ
์ ํด๋น๋๋ค
์ ๋ง์ฑ ํ๋จ ์กฐ๊ฑด1, 2
์ ์ํด 2์ฐจ์ ์ฒด์คํ์์ ๋ชจ๋ ์์น๋ฅผ ์ดํ ํ์ ์์ด ํ
ํน์ ์ด
๋จ์๋ก ํ์ธํ๋ฉด ๋จ์ ์ ์ ์๋ค.
ํ
๋จ์๋ก ๋ง์ ๋์ผ๋ฉฐ ๋ชจ๋ ํ์ ํ๋์ฉ ํธ์ ๋ฐฐ์นํ๋๋ก ํ๋ ๋ฐฑํธ๋ํน ํจ์๋ฅผ ์ ์ํด๋ณด์.
int board[N]; // ๊ฐ ํ์ ๋ํด ํธ์ด ์์นํ ์ด์ ๋ฒํธ๋ฅผ ๊ธฐ๋กํ๋ ๋ฐฐ์ด.
void bt(int rowNum) {
if (rowNum == N) { // ๋ชจ๋ ํ์ ๋ง์ ๋ค ๋์๋ค๋ฉด ์ ๋ต ๊ฐ์๋ฅผ ํ๋ ์ฆ๊ฐ์ํจ๋ค.
answer++;
return;
}
for (int colNum = 0; colNum < N; colNum++) {
// ๊ฐ ์ด์ ๋ํด ํธ์ ๋์ ์ ์๋์ง ํ์ธํ๋ค.
if (isPromissing(rowNum, colNum)) {
board[rowNum] = colNum; // rowNum ํ์ colNum ์ด์ ํธ์ ๋ฐฐ์นํ๋ค.
bt(rowNum + 1); // ์ด์ ๋ฒํธ๋ฅผ ํ๋ ์ฆ๊ฐ์ํค๋ฉฐ ์ฌ๊ท ํธ์ถํ๋ค.
board[rowNum] = 0;
}
}
}
์ด์ ์ ๋ง์ฑ์ ํ๋จํ๋ isPromissing
ํจ์๋ฅผ ์ ์ํด๋ณด์.
์์ ํจ์์ ๋ฐ๋ผ ํ๋์ ํ
์๋ ํ๋์ ํธ๋ง ๋ฐฐ์น๋๋ ๊ฒ์ด ๋ณด์ฅ๋๋ฏ๋ก ํ์ธํด์ผํ๋ ๊ฒ์ ๋๊ฐ์ง์ด๋ค.
- ๋๊ฐ์ ์์น์ ํธ์ด ์กด์ฌํ๋๊ฐ
- ๊ฐ์ ์ด์ ํธ์ด ์กด์ฌํ๋๊ฐ
bool isPromising(int currentRow, int colNum) {
for (int rowNum = 0; rowNum < currentRow; rowNum++) {
if (board[rowNum] == colNum) return false;
if (currentRow - rowNum == abs(colNum - board[rowNum])) return false;
}
return true;
}
ํ์ฌ ํธ์ ๋์ ์ ์๋ ์๋๋ฅผ ํ๋จํ๊ณ ์ ํ๋ ์์น๋ colNum
ํ์ currentRow
์ด์ด๋ค.
ํด๋น ์์น์ ๋๊ฐ์ ์ ์๋ ๋ ธ๋๋?
(x,y)์ ๋๊ฐ์ ์ ์์นํ ๋ ธ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
- (x+1, y+1), (x+2, y+2), (x+3, y+3) ...
- (x-1, y-1), (x-2, y-2), (x-3, y-3) ...
์ฆ, ํ ๋ฒํธ๊ฐ ์ฐจ์ด์ ์ด ๋ฒํธ๊ฐ ์ฐจ์ด์ ๊ฐ์ด ๊ฐ์ ๋
ธ๋๊ฐ ๋๊ฐ์ ์ ์๋ ๋
ธ๋๋ผ๋ ๊ฒ์ ์ ์ ์๋ค.
์ด๋ฅผ ๊ตฌํํ ์ฝ๋๊ฐ ๋ค์๊ณผ ๊ฐ๋ค. (isPromising
ํจ์์ ๋๋ฒ์งธ ์กฐ๊ฑด๋ฌธ)
if (currentRow - rowNum == abs(colNum - board[rowNum]))
๋ถํ ์ ๋ณต๋ฒ์ ์ ์ฒด ๋ฌธ์ ๋ฅผ ์ฌ๋ฌ ๊ฐ์ ๋ถ๋ถ ๋ฌธ์ ๋ค๋ก ๋ถํ ๊ฐ ๋ถ๋ถ ๋ฌธ์ ๋ค์ ํด๊ฒฐ(์ ๋ณต)ํจ์ ํตํด ์ ์ฒด ๋ฌธ์ ์ ํด๋ต์ ๋์ถํ๋ ๋ฐฉ์์ด๋ค. ์ด๋ Top-down approach๋ก ๋ณผ ์ ์๋ค.
- ๋ถํ (Divide) : ํด๊ฒฐํ ๋ฌธ์ ๋ฅผ ์ฌ๋ฌ ๊ฐ์ ์์ ๋ถ๋ถ์ผ๋ก (์ถฉ๋ถํ ์์์ ํด๊ฒฐํ๊ธฐ ์ฌ์ธ ๋๊น์ง) ๋๋๋ค.
- ์ ๋ณต (Conquer) : ๋๋ ๋ถ๋ถ ๋ฌธ์ ๋ฅผ ๊ฐ๊ฐ ํด๊ฒฐํ๋ค.
- ํตํฉ (Combine) : ๊ฐ ๋ถ๋ถ ๋ฌธ์ ์ ํด๋ต์ ๋ชจ์์ ์ ์ฒด ๋ฌธ์ ์ ํด๋ต์ ๋์ถํ๋ค.
์ด๋ถ ํ์ ์งํ์ ์ํด์๋ ์๋ฃ๊ฐ ์ ๋ ฌ๋ ์ํ์ฌ์ผ ํ๋ค.
์ ๋ ฌ๋ ๋ฐฐ์ด์์ ํน์ ๊ฐ X๋ฅผ ์ฐพ๊ณ ์ ํ ๋, ์ด๋ถ ํ์์ ์ด์ฉํ๋ฉด ํจ์ฌ ๋น ๋ฅด๊ฒ ๊ฒ์์ ์ํํ ์ ์๋ค.
- Divide : ๋ฐฐ์ด์ ๋ ๊ฐ์ ๋ถ๋ถ ๋ฐฐ์ด๋ก ๋๋๋ค. X๊ฐ ๊ฐ์ด๋ฐ์ ์๋ ๊ฐ๋ณด๋ค ์์ผ๋ฉด ์ผ์ชฝ ๋ถ๋ถ ๋ฐฐ์ด์, ํฌ๋ฉด ์ค๋ฅธ์ชฝ ๋ถ๋ถ ๋ฐฐ์ด์ ์ ํํ๋ค.
- Conquer : ๋ฐฐ์ด์ ๊ฐ์ด๋ฐ ๊ฐ์ด X์ ๊ฐ์์ง ๋น๊ตํ๋ค. ๊ฐ์ง ์๋ค๋ฉด Divide ๊ณผ์ ์ ์ฌ๊ท์ ์ผ๋ก ์ํํ๋ค.
- Combine : ๋ถ๋ถ ๋ฐฐ์ด์์ ์ฐพ์ ๋ต์ด ๊ณง ์ ์ฒด ํด๋ต์ด๋ค.
์ด ์ธ์๋ ๋ถํ ์ ๋ณต๋ฒ์ ํตํด MergeSort, QuickSort์ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ ์ ์์ผ๋ฉฐ, ๊ฑฐ๋ญ์ ๊ณฑ์ ๊ฒฐ๊ณผ๋ฅผ ๊ตฌํ ๋ ์๊ฐ๋ณต์ก๋๋ฅผ ์ค์ผ ์ ์๋ ๋ฐฉ๋ฒ(2^8 -> 2๋ฅผ 8๋ฒ ๊ณฑํ๊ธฐ vs ((2^2)^2)^2)์ผ๋ก ์๋ ค์ ธ ์๊ธฐ๋ ํ๋ค.
์์ธํ ์ค๋ช - ์์ฑ์ ์ฅ์ฃผ์ญ | Greedy Algorithm
ํ์ ์๊ณ ๋ฆฌ์ฆ์ ์ต์ ํด๋ฅผ ๊ตฌํ๋๋ฐ ์ฌ์ฉ๋๋ ๊ทผ์์์ ์ธ ๋ฐฉ๋ฒ์ด๋ค. ์ต์ ํ ๋ฌธ์ (optimization)๋ ๊ฐ๋ฅํ ํด๋ค ์ค์์ ๊ฐ์ฅ ์ข์ ํด๋ฅผ ์ฐพ๋ ๋ฌธ์ ์ด๋ค. Greedyํ ์ ๊ทผ์ ์ฌ๋์ ์๊ฐ๊ณผ ๋ฎ์ ์๋ค. ํ๋๋ฅผ ์ ํํ ๋๋ง๋ค ๊ทธ ์๊ฐ์ ์ต์ ์ด๋ผ๊ณ ์๊ฐ๋๋ ๊ฒ์ ์ ํํ๋ฉฐ, ํ๋ฒ ์ ํ๋ ๊ฒ์ ๋ฒ๋ณตํ์ง ์๋ ๋ฐฉ์์ผ๋ก ์งํํ์ฌ ์ต์ข ์ ์ธ ํด๋ต์ ๋๋ฌํ๊ฒ ๋๋ค. ๋จ, ์ต์ ํด๋ฅผ ๋ฐ๋์ ๊ตฌํ๋ค๋ ๋ณด์ฅ์ด ์๊ธฐ ๋๋ฌธ์ ์ฆ๋ช ๊ณผ์ ์ด ํ์ํ๋ค.
์ต์ ํด๋ฅผ ๋ฐ๋์ ๊ตฌํ๋ค๋ ๋ณด์ฅ์ด ์๋ค.
์ต์์ ๋์ ์ผ๋ก 800์์ ๋ง๋ค๊ณ ์ ํ ๋, Greedyํ ์ ๊ทผ์ผ๋ก๋ ํฐ ๋์ ๋ถํฐ ์ ํํ๋ฉด ๋ ๊ฒ์ด๋ค. ํ์ง๋ง ๊ทธ๋ฌ์ ๋ ์ต์ ํด๋ฅผ ์ฐพ์ ์ ์๋ ๊ฒฝ์ฐ๋ ์๋ค.
- ๋์ ์ข ๋ฅ๊ฐ 500, 100, 50, 10์ผ ๊ฒฝ์ฐ : 500์ 1๊ฐ, 100์ 3๊ฐ
- ๋์ ์ข ๋ฅ๊ฐ 500, 400, 100, 50, 10์ผ ๊ฒฝ์ฐ : 500์ 1๊ฐ, 100์ 3๊ฐ > 400์ 2๊ฐ
ํ์ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ์๋ ๋ ๊ฐ์ง ์์ฑ์ ๋ง์กฑํจ์ ์ฆ๋ช ํด์ผ ํ๋ค.
- ํ์์ ์ ํ ์์ฑ (greedy choice property) : ํ์์ ์ผ๋ก๋ง ์ ํ์ ํด๋ ์ต์ ํด๋ฅผ ๊ตฌํ ์ ์๋ค.
- ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ (optimal substructure property) : ๋ถ๋ถ ๋ฌธ์ ์ ์ต์ ํด์์ ์ ์ฒด ๋ฌธ์ ์ ์ต์ ํด๋ฅผ ๋ง๋ค ์ ์๋ค.
- ํ๋ฆผ(Prim) ์๊ณ ๋ฆฌ์ฆ : ํ์ฌ ์ ์ ์ ์ฐ๊ฒฐ๋ ๊ฐ์ ๋ค ์ค ๊ฐ์ค์น๊ฐ ์์ ๊ฐ์ ๋ถํฐ ์ ํํ๋ค.
- ํฌ๋ฃจ์ค์นผ(Kruskal) ์๊ณ ๋ฆฌ์ฆ : ๊ฐ ๋จ๊ณ์์ ๊ฐ์ค์น๊ฐ ์์ ๊ฐ์ ๋ถํฐ ์ ํํ๋ค.
- ๋ค์ต์คํธ๋ผ(Dijkstra) ์๊ณ ๋ฆฌ์ฆ : ํ์ฌ ์ ์ ์์ ๊ฐ์ฅ ๊ฐ๊น์ด ์ ์ ์ ์ ํํ๋ค.
๋์ ๊ณํ๋ฒ์ ์ฃผ์ด์ง ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ฌ๋ฌ ๊ฐ์ ํ์ ๋ฌธ์ ๋ก ๋๋์ด ํผ ๋ค์ ๊ฒฐํฉํ์ฌ ๋ต์ ์ฐพ๋ ๋ฐฉ๋ฒ์ด๋ค. ๋ฌธ์ ํด๊ฒฐ์ ์ํด์๋ ๋ค์ํ ๋ฐฉ๋ฒ์ผ๋ก ํ์ ๋ฌธ์ ๋ก ๋๋์ด ๋ณด๊ณ ์ฃผ์ด์ง ์๊ฐ ๋ณต์ก๋ ๋ด์์ ์ํ์ด ๊ฐ๋ฅํ ์ต์ ์ ์ ํ์์ ์ฐพ๋ ๊ฒ์ด ํต์ฌ์ด๋ค.
๋์ ๊ณํ๋ฒ์ ์ ์ฉํ ๋ํ์ ์ธ ๋ฌธ์ ๋ก๋ ๋ฐฐ๋ญ ์ง์ธ๊ธฐ ๋ฌธ์ (Knapsack Problem), ์ต์ฅ์ฆ๊ฐ์์ด(LIS, Longest Increasing Subsequence), ์ธํ์ ์ํ ๋ฌธ์ (TSP, Traveling Salesman Problem) ๋ฑ์ด ์๋ค. ์ด ๋ฐ์๋ memoization ๋ฐ ์ ํ์์ ํตํด ๋ค์ํ ๋ฌธ์ ๋ฅผ ํจ์ฌ ํจ์จ์ ์ธ ๋ฐฉ์์ผ๋ก ํด๊ฒฐํ ์ ์๋ค.
"ํฐ ๋ฌธ์ ๋ฅผ ์ฌ๋ฌ๊ฐ์ ํ์ ๋ฌธ์ ๋ก ๋๋์ด ํผ๋ค" ๋ผ๋ ์ ์์ DP๋ ๊ทธ ํ์์ ๊ฐ์ด ๊ณ์ ๋ณํ๊ณ , DAC๋ ๋ณํ์ง ์๋๋ค๋ ์ฐจ์ด์ ์ด ์๋ค.
Knapsack
์๊ณ ๋ฆฌ์ฆ์ ํฌ๊ฒ ๋๊ฐ์ง๋ก ๋๋ ์ ์๋ค.
- Fractional Knapsack
- 0-1 Knapsack
Fractional Knapsack
์ ๊ฒฝ์ฐ ํ์ ๊ธฐ๋ฒ์ ์ฌ์ฉํด์ ํด๊ฒฐํ ์ ์๋ค.
๋ฐ๋ฉด 0-1 Knapsack
์ ๊ฒฝ์ฐ ํ์ ๊ธฐ๋ฒ์ ํตํด์๋ ์ ํด๋ฅผ ๋ณด์ฅํ ์ ์๊ณ ๋์ ํ๋ก๊ทธ๋๋ฐ์ ์ฌ์ฉํด์ ํด๊ฒฐํ ์ ์๋ค.
- N๊ฐ์ ๋ณด์์ด ์๋ค.
- ๋ณด์๋ค์ ๊ฐ ๋ณด์๋ง๋ค ๊ฐ๊ฒฉ(V)๊ณผ ๋ฌด๊ฒ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
- ๋๋์ด ๋ณด์์ ํ์น๋ ค๊ณ ํ๋ค! ํ์ง๋ง ๋๋์ ๊ฐ๋ฐฉ์๋ ์ ํด์ง ๋ฌด๊ฒ(W) ๋ฐ์ผ๋ก๋ง ๋ด์ ์ ์๋ค.
- ๋๋์ด ๋ฐฐ๋ญ ์์ ๋ด์ ๋ณด์์ ๊ฐ๊ฒฉ์ ํฉ์ด ์ต๋๊ฐ ๋๋๋ก ํ๋ผ.
๋์ ๊ณํ๋ฒ์ ๊ธฐ๋ณธ์ ์ธ ๋ฉ์ปค๋์ฆ์ ์ํด, ์ด์ ๋จ๊ณ์์ ๊ตฌํ๋ ์ต์ ํด๊ฐ ๋ค์ ๋จ๊ณ์์ ์ต์ ํด๋ฅผ ๊ตฌํ๋๋ฐ ํฌํจ๋จ์ ๊ธฐ์ตํ๋ฉฐ ์ ํ์์ ์ค๊ณํด๋ณด์.
KNAPSACK(i, w) : 1~i ๋ฒํธ๊น์ง์ ๋ณด์ ์ค ๋ฐฐ๋ญ์ ์ต๋ ๋ฌด๊ฒ๊ฐ w์ผ ๋์ ๊ฐ์ง ์ ์๋ ์ต๋์ ๋ณด์๊ฐ๊ฒฉํฉ.
์ด๋ฌํ ์์ ์ค๊ณํ๋ค๊ณ ํ์ ๋, ์ฐ๋ฆฌ๊ฐ ์ํ๋ ์ต์ ํด๋ KNAPSACK(N, W)
๊ฐ ๋ ๊ฒ์ด๋ค.
๋ฐฐ๋ญ ๋ฌด๊ฒ๋ฅผ 1๋ถํฐ W๊น์ง ๋๋ ค๊ฐ๋ฉฐ, ๋ณด์์ ๋ฃ๋๋ค๊ณ ํด๋ณด์.
์ด ๋ ๋ค์ ๋ณด์์ ๋ฃ๊ธฐ ์ ๊ณ ๋ คํด์ผํ ๊ฒฝ์ฐ์ ์๊ฐ 3๊ฐ์ง ์๋ค.
-
๋ค์ ๋ณด์์ ๋ฐฐ๋ญ์ ๋ด์ ์ ์๋ค.
-
๋ค์ ๋ณด์์ ๋ฐฐ๋ญ์ ๋ด์ ์ ์๋ค.
2-1. ๋ค๋ฅธ ๋ณด์์ ๋นผ๊ณ ํ์ฌ ๋ณด์์ ๋ด๋๋ค.
2-2. ๋ค๋ฅธ ๋ณด์๊ณผ ํจ๊ป ํ์ฌ ๋ณด์์ ๋ด๋๋ค.
๋ณด์์ ๋ด์ ์ ์๋ ์กฐ๊ฑด์ ๋ค์๊ณผ ๊ฐ๋ค.
- ํ์ฌ ๋ณด์์ ๋ฌด๊ฒ๊ฐ ๊ฐ๋ฐฉ์ ๋ฌด๊ฒ๋ณด๋ค ๋ฌด๊ฒ๋ค.
- ๋ค๋ฅธ ๋ณด์์ ๋นผ๊ณ ๋ฃ์์ ๋ ์ด์ ๋จ๊ณ๋ณด๋ค ๋ฎ์ ๊ฐ์น๋ฅผ ๊ฐ์ง๋ค.
KNAPSACK(N, W)
๋ ๊ฒฐ๊ตญ KNAPSACK(N-1, w)
์ ์ฐ๊ด์ ๊ฐ๊ฒ ๋๋ค.
์ฆ, ์ด์ ๋ณด์ ๋ฒํธ์ ์ต์ ํด ๊ฐ์ ์ฌ์ฉํ์ฌ ๊ตฌํ๊ฒ ๋๋ ๊ฒ์ด๋ค.
์์ ์กฐ๊ฑด๋ค์ ๊ณ ๋ คํ์ฌ ์ ํ์์ ์ธ์๋ณผ ์ ์๊ฒ ๋ค.
(if w[i] > w) KNAPSACK(i-1, w)
KNAPSACK(i, w) =
(if w[i] <= w) max(KNAPSACK(i-1, w), KNAPSACK(i-1, w-w[i]) + V[i])
์์ ์ ํ์์ ์ฌ์ฉํด ๋ณด์ ๋ฒํธ 1๋ถํฐ N๊น์ง, ๋ฐฐ๋ญ ๋ฌด๊ฒ๋ฅผ 1๋ถํฐ W๊น์ง ๋ฐ๋ณตํ๋ฉฐ ์ด์ฐจ์ ๋ฐฐ์ด์ ์ฑ์๋๊ฐ๋ฉด ๋๋ค.
์ด๋ฌํ ํ์ด๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค๋ฉด ๋ฐฐ๋ญ๋ฌธ์ ๋ฅผ O(N*W)
์ ์๊ฐ๋ณต์ก๋๋ก ํด๊ฒฐ ํ ์ ์๊ฒ ๋๋ค.