Dynamic Programming - GitDeveloperKim/DreamEach GitHub Wiki
-
๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ ํ ์ฌ์ฉํ์ฌ ์ํ ์๊ฐ ํจ์จ์ฑ์ ๋น์ฝ์ ์ผ๋ก ํฅ์์ํค๋ ๋ฐฉ๋ฒ
-
์ด๋ฏธ ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ ๋ณ๋์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ ์ฅํ์ฌ ๋ค์ ๊ณ์ฐํ์ง ์๋๋ค
-
๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ ๊ตฌํ์ ์ผ๋ฐ์ ์ผ๋ก ๋๊ฐ์ง ๋ฐฉ์์ผ๋ก ๊ตฌ์ฑ (bottom-up, top-down)
-
๋ค์์ ์กฐ๊ฑด์ ๋ง์กฑํ ๋ ์ฌ์ฉ ๊ฐ๋ฅ
- ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ (Optimal Substructure)
- ํฐ ๋ฌธ์ ๋ฅผ ์์ ๋ฌธ์ ๋ก ๋๋ ์ ์์ผ๋ฉฐ ์์ ๋ฌธ์ ์ ๋ต์ ๋ชจ์์ ํฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐ
- ์ค๋ณต ๋ถ๋ถ ๋ฌธ์ (Overlapping Subproblem)
- ๋์ผํ ์์ ๋ฌธ์ ๊ฐ ๋ฐ๋ณต์ ์ผ๋ก ํด๊ฒฐ
- ํ๋ฒ ๊ณ์ฐํ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๋ฉ๋ชจํ๋ ๊ธฐ๋ฒ
- ๊ฐ์๋ฌธ์ ๋ฅผ ๋ค์ ํธ์ถํ๋ฉด ๋ฉ๋ชจํ๋ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ด
- ๊ฐ์ ๊ธฐ๋กํด ๋๋๋ค๋ ์ ์์ ์บ์ฑ(caching)
- ์ ํ์์ด๋ ์ธ์ ํ ํญ๋ค ์ฌ์ด์ ๊ด๊ณ์
- knapsack์ ์ฌ๋ฌ ๋ฌผ๊ฑด์ด ์์ ๋ ํน์ ํ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์กฐํฉ์ ๊ตฌํ๋ ๋ฌธ์ ๋ฅผ ์๋ฏธํ๋ค
- ์ต์ ์ ์๋ฆฌ(Principle of Optimality) : ์ด๋ค ๋ฌธ์ ์ ์ ๋ ฅ ์ฌ๋ก์ ์ต์ ํด๊ฐ ๊ทธ ์ ๋ ฅ ์ฌ๋ก๋ฅผ ๋ถํ ํ ๋ถ๋ถ ์ฌ๋ก์ ๋ํ ์ต์ ํด๋ฅผ ํฌํจํ๊ณ ์์ผ๋ฉด, ๊ทธ ๋ฌธ์ ์ ๋ํ์ฌ ์ต์ ์ ์๋ฆฌ๊ฐ ์ฑ๋ฆฝํ๋ค.
- dp[i][w] : ๋ฐฐ๋ญ์ ๋จ์ ๋ฌด๊ฒ(ํ๋)๊ฐ w์ผ๋ i๋ฒ์งธ ๋ณด์(๋ฌผ๊ฑด)๊น์ง ์ฌ์ฉํ์ฌ ์กฐํฉ ๊ฐ๋ฅํ ์ต๋ ๊ฐ์นํฉ
- ๋ณด์์ด ์ ํํ ๋ (0-1)
-> if (j-w[i] < 0) : dp[i-1,w] // ์ฑ์ธ ์ฉ๋์ด ์์ ๋ i๋ฒ์งธ ๋ณด์ ์ ๋ฃ๊ณ ์ด์ ๊ฐ ๊ฐ์ ธ์ค๊ธฐ
-> else(j-w[i] >=0) : max(value[i] + dp[i-1][j-w[i]] , dp[i-1][j]) // i ๋ฒ์งธ ๋ณด์์ ์ ๋ฃ๊ณ ๊ทธ๋๋ก ๊ฐ์ ธ์ค๋ ๊ฒ๊ณผ i๋ฒ์งธ ๋ณด์์ ๋ฃ์ ๋ ๋น๊ต - ๋ณด์์ด ๋ฌดํํ ๋
-> ์ด์ ์ ์ฑ์ ๋ ๊ฒ์ ๋ด ๋ฌด๊ฒ๋ฅผ ๋ํ ๊ฒ๊ณผ ์ด์ ์ ๊ตฌํ ๊ฐ๊ณผ ๋น๊ตํ์ฌ ๊ฐ์น๊ฐ ๋ ํฐ๊ฒ์ ํํ๋ค
-> dp[i][j] = max(dp[i][j-1], dp[i][j-w[i]]+value[i]) // i๋ฒ์งธ ๋ณด์์ ์์ฐ๋ ๊ฒฝ์ฐ์ ์ด์ ๊ฐ์ i๋ฒ์งธ ๋ณด์์ ์ถ๊ฐํ๋ ๊ฒ ๋น๊ต
click
click
import java.util.Scanner;
public class Main {
public static int N,K;
public static int []w = new int[100000];
public static int []v = new int[100000];
public static int [][] d = new int [101][100001];
// d[i,w] : i๊ฐ์ ๋ณด์์ด ์๊ณ ๋ฐฐ๋ญ์ ๋ฌด๊ฒํ๋๊ฐ w์ผ๋ ์ต์ ์ ์ด์ต
public static void main(String[] args) {
Scanner in = new Scanner (System.in);
N = in.nextInt(); // ๋ณด์์ ๊ฐ์
K = in.nextInt(); // ์ต๋ ์ฉ๋
for (int i = 1; i <= N; i++) {
w[i] = in.nextInt(); // ๋ณด์์ ๋ฌด๊ฒ
v[i] = in.nextInt(); // ๋ณด์์ ๊ฐ์น
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= K; j++) {
if (j-w[i] >= 0) {
d[i][j] = Math.max(d[i-1][j],d[i-1][j-w[i]] + v[i]);
} else {
d[i][j] = d[i-1][j];
}
}
}
System.out.println(d[N][K]);
}
}
| dp[i][j] (๋ฌด๊ฒ/๊ฐ) | dp[][1] | dp[][2] | dp[][3] | dp[][4] | dp[][5] | dp[][6] | dp[][7] |
|---|---|---|---|---|---|---|---|
| 1๋ฒ๋ณด์ (6/13) | 0 | 0 | 0 | 0 | 0 | 13 | 13 |
| 2๋ฒ๋ณด์ (4/8) | 0 | 0 | 0 | 8 | 8 | 13 | 13 |
| 3๋ฒ๋ณด์ (3/6) | 0 | 0 | 6 | 8 | 8 | 13 | 14 |
| 4๋ฒ๋ณด์ (5/12) | 0 | 0 | 6 | 8 | 12 | 13 | 14 |
- lis์ ๊ธธ์ด๋ฅผ ๊ตฌํ๋ 3๊ฐ์ง ๋ฐฉ๋ฒ
- lis์ ๊ธธ์ด ๊ตฌํ๊ธฐ ์ต์ ํ
- ๋ฐฑ์ค 2352 ๋ฌธ์
- ๋ฐฑ์ค 2352 ํ์ด
- lis ๊ฐ๋
n = Integer.parseInt(br.readLine());
input = new int[n+1];
dp = new int [n+1];
st = new StringTokenizer(br.readLine(), " ");
for (int i = 1; i <= n; i++) {
input[i] = Integer.parseInt(st.nextToken());
}
dp[1] = input[1];
int index = 1;
for (int i = 2; i <= n; i++) {
if (dp[index] < input[i]) {
dp[++index] = input[i];
} else {
/*
int j = 1;
for (j = 1; j <= index;j++) {
if (dp[j] >= input[i])
break;
}*/
dp[lower_bound(1,index,input[i])] = input[i];
}
}
sb.append(index+"\n");
- lower bound
private static int lower_bound (int s, int e, int v) {
while (s < e) {
int mid = (s+e)/2;
// v ์ฐพ๊ณ ์ ํ๋ ๊ฐ, dp[mid] ๋ฐฐ์ด์์ ์ค์๊ฐ
if (v <= dp[mid]) {
e = mid;
} else {
s = mid+1;
}
}
return e;
}
- upper bound
private static int upperBound(List data, int target) {
int begin = 0;
int end = data.size();
while(begin < end) {
int mid = (begin + end) / 2;
if(data.get(mid) <= target) {
begin = mid + 1;
}
else {
end = mid;
}
}
return end;
}