permutation && combination
๐โโ๏ธ๋ค์ด๊ฐ๋ฉฐ
์ด๋ฒ์ ํ์ตํ ๋ด์ฉ์ ์์ด ๊ทธ๋ฆฌ๊ณ ์กฐํฉ์ด๋ค
์์ด์ ์ค๋ณต์ด ๊ฐ๋ฅํ๊ณ , ์กฐํฉ์ ์ค๋ณต์ด ๋ถ๊ฐ๋ฅํ๋ค.
- ์์ด ex) -> ์๋ฆฌ ๋ฐฐ์น
- ์กฐํฉ ex) -> ์๋ฆฌ์ฌ๋ฃ ์ ํ
์์ด์ ๊ฒฝ์ฐ ๊ทธ๋ฅ factorial์ ํตํด ๊ตฌํํ๋ฉด ๋๊ฒ ๋ค
โฒpermutation
P = $\frac{n!}{(n-r)!}$
์นด๋ 5๊ฐ ์ค 2๊ฐ ๊ณ ๋ฅด๊ธฐ
${5}P{2}$ -> 20
๐combination
์กฐํฉ์ด๋ค
\[\binom{n}{k} = \frac{n!}{k!(n-k)!}\]ํผ์๋ฅผ ๋ง๋ค๊ธฐ ์ํด ์ฌ๋ฃ a,b,c,d,e ์ค 3๊ฐ๋ง ๊ณ ๋ฅด๊ฒ ๋ค.
์ ์ฒด ๊ฒฝ์ฐ์ ์ = (ํน์ x๋ฅผ ์ ํํ ๊ฒฝ์ฐ์ ์) + (ํน์ x๋ฅผ ๋ฏธ์ ํํ ๊ฒฝ์ฐ์ ์)
์ด๊ฑธ ๋ํ๋ด๋ฉด ์๋์ ๊ฐ๊ฒ ๋ค
${5}C{3} = {4}C{2} + {4}C{3}$
๊ทธ๋ฌ๋ฉด ์ ์ฒด ์กฐํฉ์ ๊ฒฝ์ฐ์ ์์ธ 10๊ฐ์ง๊ฐ ๋์ถ๋๋ค.
์ด๊ฑธ ์ฝ๋๋ก ๋ํ๋ด๋ฉด ์๋์ ๊ฐ๊ฒ ๋ค
1
C[5][3] = C[4][2] + C[4][3]
์กฐํฉ - ์ผ๋ฐ์ ํ์ ์ฝ๋
์ด๊ฑธ ์ผ๋ฐ ์ ํ์ ์ฝ๋๋ก ๋ํ๋ด๋ฉด ์๋์ ๊ฐ๊ฒ ๋ค
1
C[r][c] = C[r-1][c-1] + C[r-1][c-1]
โฑ๏ธ์๊ฐ๋ณต์ก๋
permutation
- O(n!)
combination
- ์กฐํฉ ์ ํ์ DP -> O(nr)
- DP ํ์ค์นผ ๋ฐฉ์ -> O($N^2$)
์ฌ๊ท ํฉํ ๋ฆฌ์ผ ๋ฐฉ์ O(N) ์ ๋ ๊ธ์ง!!! why?? -> overflow
์์
boj_์ดํญ๊ณ์1_11050
2๊ฐ์ง ํ์ด๋ฅผ ๋ณด์ฌ์ฃผ๊ฒ ๋ค
1๋ฒ ํ์ด (๊ฐ๋ ฅ ๋น์ถ โ๏ธ)
O(N) ์ด์ง๋ง ์ ๋ง ์ด๊ฑฐ ์ฐ๋ฉด ์๋๋ค
๋ฌธ์ ์กฐ๊ฑด์์ N <= 10, K <= N ์ด์ง๋ง, ๋ง์ฝ N = 13 ์ด๋ฉด 13! ์ผ๋ก int ์ด๊ณผ, ๊ทธ๋ฆฌ๊ณ 19! ๋ผ๋ฉด long ๋ฒ์๋ ์ด๊ณผํด์ ๊ฒฐ๊ตญ value overflow๊ฐ ๋ฐ์ํ๋ค.
ํ์ง๋ง ์ผ๋จ ํด๋น ๋ฌธ์ ๋ N <= 10, K <= N์ด์๊ธฐ์ ์๋ ๊ณต์์ ์ ์ฉํ์ฌ ํ ์ ์์๋ค
$ \binom{N}{K} = \frac{N!}{K!(N-K)!} $
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] NK = br.readLine().split(" ");
int N = Integer.parseInt(NK[0]);
int K = Integer.parseInt(NK[1]);
C(N, K);
}
static void C(int N, int K) {
int denominator = 1;
int numerator_1 = 1;
int numerator_2 = 1;
denominator = recursion(N);
numerator_1 = recursion(K);
numerator_2 = recursion(N-K);
int res = denominator / (numerator_1 * numerator_2);
System.out.println(res);
}
static int recursion(int x) {
if (x <= 1) {
return 1;
}
return x * recursion(x-1);
}
}
2๋ฒ ํ์ด (๋ฌด์กฐ๊ฑด ์ด๊ฑฐ ์จ๋ผ โ
๏ธ)
DP ํ์ค์นผ ๋ฐฉ์์ผ๋ก $O(N^2)$
N, K๊ฐ ์ปค์ง์๋ก, ๊ทธ๋ฅ ๋ฌป์ง๋ง๊ณ
์ด๊ฑฐ ๋ฅ์ฌ์ฉ์ด๋ค.
์??? -> value overflow๊ฐ ์ ์๋๊ธฐ ๋๋ฌธ์ด๋ค
๐ช๊ตฌ์ถ ์์
- ๋ฐฐ์ด ํฌ๊ธฐ ์ ์ธ
- N=5์ผ๋ -> DP[5+1][5+1]
- for๋ฌธ์ผ๋ก ์ด๊ธฐ ์ธํ
- i๊ฐ์ค 1๊ฐ ๋ฝ๊ธฐ -> i๊ฐ
- i๊ฐ์ค 0๊ฐ ๋ฝ๊ธฐ -> 1๊ฐ
- i๊ฐ์ค i๊ฐ ๋ฝ๊ธฐ -> 1๊ฐ
- DP ํ์ค์นผ ์ ํ์ ์ ์ฉ DP[r][c] = DP[r-1][c-1] + DP[r-1][c]
2๋ฒ๊ณผ์ ๊น์ง ์ํํ๊ณ ์ถ๋ ฅ์ผ๋ก ํ์ธํ๋ฉด ์๋์ ๊ฐ์ ๊ฒ์ด๋ค
| ย | ย | ย | ย | ย | ย |
|---|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 | 0 | 0 |
| 1 | 2 | 1 | 0 | 0 | 0 |
| 1 | 3 | ย | 1 | 0 | 0 |
| 1 | 4 | ย | ย | 1 | 0 |
| 1 | 5 | ย | ย | ย | 1 |
์ค ์ผ์ชฝ์์์ ์ค๋ฅธ์ชฝ ์๋๋ก ๋ด๋ ค๊ฐ๋ ๋๊ฐ์ ์ 1๋ก ์ฑ์์ก์ผ๋ ์ ๊ฑธ ๊ฑด๋๋ฆฌ์ง ์๊ณ
์์๋ง ์ซ์ ๊ฐฑ์ ํ๋ ๋ฒ์ด ์์๊น?
c๊ฐ r๋ณด๋จ ๋ฌด์กฐ๊ฑด ์์์ผ๊ฒ ๋ค
๊ทธ๋ฌ๋ฉด ์ด์ ๋จ์ ๊ณณ์ DP ํ์ค์นผ๋ก ์ฑ์๋ณด์
| ย | ย | ย | ย | ย | ย |
|---|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 | 0 | 0 |
| 1 | 2 | 1 | 0 | 0 | 0 |
| 1 | 3 | 3 | 1 | 0 | 0 |
| 1 | 4 | 6 | 4 | 1 | 0 |
| 1 | 5 | 10 | 10 | 5 | 1 |
์ผ๋จ ์์ฑ์ด ๋ ๊ฒ ๊ฐ๋ค
์ด์ ๊ฒ์ฆํด๋ณด์
${0}C{0}$ ย ${0}C{1}$ ย ${0}C{2}$ ย ${0}C{3}$ ย ${0}C{4}$ ย ${0}C{5}$
${1}C{0}$ ย ${1}C{1}$ ย ${1}C{2}$ ย ${1}C{3}$ ย ${1}C{4}$ ย ${1}C{5}$
${2}C{0}$ ย ${2}C{1}$ ย ${2}C{2}$ ย ${2}C{3}$ ย ${2}C{4}$ ย ${2}C{5}$
${3}C{0}$ ย ${3}C{1}$ ย ${3}C{2}$ ย ${3}C{3}$ ย ${3}C{4}$ ย ${3}C{5}$
${4}C{0}$ ย ${4}C{1}$ ย ${4}C{2}$ ย ${4}C{3}$ ย ${4}C{4}$ ย ${4}C{5}$
${5}C{0}$ ย ${5}C{1}$ ย ${5}C{2}$ ย ${5}C{3}$ ย ${5}C{4}$ ย ${5}C{5}$
๋ง์ฝ ์์ ๋ฌธ์๊ฐ ๊นจ์ ธ๋ณด์ธ๋ค๋ฉด ์๋ ์ฌ์ง๊ณผ ๊ฐ์ ๋ด์ฉ์ด๋ ์๋ ์ฌ์ง์ ๋ณด์
๋ง๋ค
์ฝ๋
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] NK = br.readLine().split(" ");
int N = Integer.parseInt(NK[0]);
int K = Integer.parseInt(NK[1]);
lets_solve_this(N, K);
}
static void lets_solve_this(int N, int K) {
// ๋ฐฐ์ด ํฌ๊ธฐ ์ ์ธ
int[][] DP = new int[N+1][N+1];
// for๋ฌธ์ผ๋ก ๋ฐฐ์ด ๋งค ๋ฐ๋ณต๋งํ ์
๋ ฅ
for (int i = 0; i < N+1; i++) {
// i๊ฐ์ค 1๊ฐ ๋ฝ๊ธฐ
DP[i][1] = i;
// i๊ฐ์ค 0๊ฐ ๋ฝ๊ธฐ
DP[i][0] = 1;
//i๊ฐ์ค i๊ฐ ๋ฝ๊ธฐ
DP[i][i] = 1;
}
// ๋จ์ ์นธ ์ฑ์ฐ๊ธฐ
// c๋ r์ ์ ๋ ๋์ผ๋ฉด ์๋ผ~
for (int r = 3; r < N+1; r++) {
for (int c = 2; c < r; c++) {
DP[r][c] = DP[r-1][c-1] + DP[r-1][c];
}
}
// result
System.out.println(DP[N][K]);
}
}


