12865๋ฒ: ํ๋ฒํ ๋ฐฐ๋ญ
์ฒซ ์ค์ ๋ฌผํ์ ์ N(1 ≤ N ≤ 100)๊ณผ ์ค์๊ฐ ๋ฒํธ ์ ์๋ ๋ฌด๊ฒ K(1 ≤ K ≤ 100,000)๊ฐ ์ฃผ์ด์ง๋ค. ๋ ๋ฒ์งธ ์ค๋ถํฐ N๊ฐ์ ์ค์ ๊ฑฐ์ณ ๊ฐ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ W(1 ≤ W ≤ 100,000)์ ํด๋น ๋ฌผ๊ฑด์ ๊ฐ์น V(0 ≤ V ≤ 1,000)
www.acmicpc.net
์๊ณ ๋ฆฌ์ฆ [์ ๊ทผ ๋ฐฉ๋ฒ]
์ด ๋ฌธ์ ๋ ๋ฐฐ๋ญ ๋ฌธ์ (knapsack)๋ก ๋งค์ฐ ์ ๋ช ํ ๋ฌธ์ ๋ค. ๋ฌธ์ ์ค๋ช ์ฒ๋ผ ๋ฐฐ๋ญ์ ๋ฃ์ ์ ์๋ ์ต๋๊ฐ์ด ์ ํด์ง๊ณ ํด๋น ํ๋ ๋ฌผ๊ฑด์ ๋ฃ์ด ๊ฐ์น์ ํฉ์ด ์ต๋๊ฐ ๋๋๋ก ๊ณ ๋ฅด๋ ๋ฐฉ๋ฒ์ ์ฐพ๋ ๊ฒ์ด๋ค. ์ฆ, ์กฐํฉ ์ต์ ํ ๋ฌธ์ ๋ค.
๋ฐฐ๋ญ๋ฌธ์ , ์ผ๋ช ๋ ์ ์๊ณ ๋ฆฌ์ฆ์ ํฌ๊ฒ ๋ ๊ฐ์ง ๋ฌธ์ ๋ก ๋ถ๋ฅ ๋ ์ ์๋๋ฐ, ์ง์ ์ชผ๊ฐค ์ ์๋ ๊ฒฝ์ฐ์ ์ง์ ์ชผ๊ฐค ์ ์๋ ๊ฒฝ์ฐ๋ก ๋๋ ์ ์๋ค. ์ง์ ์ชผ๊ฐค ์ ์๋ ๋ฐฐ๋ญ๋ฌธ์ ๋ฅผ Fraction Knapsack Problem ์ด๋ผ ํ๊ณ , ์ง์ ์ชผ๊ฐค ์ ์๋ ๋ฐฐ๋ญ๋ฌธ์ ๋ฅผ 0/1 Knapsack Problem ์ด๋ผ ํ๋ค. ์๊ณ ๋ฆฌ์ฆ ๋ํ ๋ค๋ฅด๊ฒ ์ ์ฉํ๋๋ฐ, Fraction Knapsack Problem ์ ๊ฒฝ์ฐ ํ์ ์๊ณ ๋ฆฌ์ฆ(Greedy)์ ์ฐ๋ฉฐ, 0/1 Knapsack Problem์ ๊ฒฝ์ฐ DP ๋ฒ์ ์ด๋ค. (๋ฌผ๋ก FPTAS(Fully polynomial time approximation scheme) ์ผ๋ก ์ค์ผ์ผ๋ง์ ํตํ ๋ฐฉ๋ฒ๋ ์์ง๋ง ๊ทผ์ฌ์น๋ฅผ ์ป๋ ๋ฐฉ๋ฒ์ธ์ง๋ผ ์์นซ ํ๋ฆด ์๋ ์๋ค.)
์ด๋ฒ ๋ฌธ์ ๋ ์ง์ ์ชผ๊ฐค ์ ์๊ธฐ ๋๋ฌธ์ ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ(DP)๋ก ํด๊ฒฐํด์ผํ๋ค.
์ด์ ์ LCS๋ฌธ์ ๋ฅผ ํ์๋ ๊ฒ์ฒ๋ผ ํ ๋ฒ ํ๋ฅผ ๊ทธ๋ ค๋ณด์.
๋จผ์ ๋ฌด๊ฒ W[] ๋ฐฐ์ด๊ณผ ๊ฐ์น V[] ๋ฐฐ์ด์ด ์๋ค๊ณ ํ ๋, ๊ฐ W[i] ์ ๋ฌด๊ฒ์ ๋์๋๋ ๊ฐ์น๋ V[i]๋ค. ์ฆ, (Wi, Vi) ๋ผ๊ณ ํ ๋, ์ ์์ ๋ก๋ ๋ค์๊ณผ ๊ฐ๋ค.
(Wi, Vi) = (6, 13), (4, 8), (3, 6), (5, 12)
๊ทธ๋ฆฌ๊ณ ๋ฐฐ๋ญ์ด ์์ฉ ๊ฐ๋ฅํ ์ต๋ ๋ฌด๊ฒ K = 7 ์ด๋ค.
์ด๋ฅผ ํ ๋๋ก ์์ฉ๊ฐ๋ฅํ ์ต๋ ๋ฌด๊ฒ์ ๋ฐ๋ฅธ i๊น์ง์ ๊ฐ ๋ฌผํ ๋ฐ ๊ฐ์น๋ฅผ ํ๋ก ๊ทธ๋ ค๋ณด๋ฉด ๊ท์น์ ๋ฐ๊ฒฌํ ์ ์๋ค. dp(์์ฉ๊ฐ๋ฅํ ๋ฌด๊ฒ)๋ฅผ 0๋ถํฐ ํ๋์ฉ ์ฑ์๋ณด๋๋ก ํ์. (์ฐธ๊ณ ๋ก ์ธ๋ก์ค์ ~๊น์ง ํ์ํ๋ค๋ ์๋ฏธ๋ค.)
๋น์ฐํ dp[0] ์ ์์ฉ๊ฐ๋ฅํ ๋ฌด๊ฒ๊ฐ 0์ด๋ฏ๋ก ๋ชจ๋ 0์ผ ๊ฒ์ด๋ค..
dp[1], dp[2] ๋ํ ์์ฉ๊ฐ๋ฅํ ๋ฌผ๊ฑด์ด ์์ผ๋ฏ๋ก ๋ชจ๋ 0์ผ๋ก ์ฑ์ฐ์.
๋ค์๋ถํฐ๋ ์ด์ ์ฑ์ธ ๊ฒ์ด ์๊ธด๋ค. ์ผ๋จ dp[3] ์ฆ, ๋ฌด๊ฒ 3์ ์์ฉ ํ ์ ์๋ ๊ฒ์ i = 3 ์ผ ๋๋ถํฐ์ด๋ค. ์ฆ, ์๋์ ๊ฐ๋ค.
์? ์ i=4 ์ผ ๋๋ 6์ผ๋ก ์ฑ์์ง๋์? ๋ผ๊ณ ๋ฌป๋๋ค๋ฉด ์์ ๋งํ์ง๋ง ์ธ๋ก์ค์ ~๊น์ง ํ์ํ๋ค๋ ์๋ฏธ๋ผ๊ณ ํ๋ค. ์ฆ, i=3์ ๋ํด ํ์ํ๋๋ฐ ๋ฌด๊ฒ 3์ ๋์๋๋ 6์ ๋ด์ ์ ์์ด dp[3]์ ์ ์ฅ๋์๋ค. ๊ทธ ๋ค์์ i=4๋ฅผ ํ์ํ ํ ๋ฐ, W[4] = 5 ์ด๋ฏ๋ก ๋ฌด๊ฒ๊ฐ 5๋ผ๋ ์๋ฏธ์ด๋ฏ๋ก ์ฑ์ธ ์ ์๊ณ ์ด์ i=3 ์ ๋ํ์ฌ ํ์ํ ๋์ ์ฑ์์ง ๊ฐ์ ๊ทธ๋๋ก ๊ฐ๊ณ ์๊ฒ ๋๋ ๊ฒ์ด๋ค. (๋์ ํ์์ด๋ผ ํ๋ฉด ์ดํด๊ฐ ๋ ๋ ค๋..)
์ผ๋จ ์ฐจ๊ทผ์ฐจ๊ทผ ์ฑ์๋ณด๋ฉด ์ดํด ๊ฐ ๊ฒ์ด๋ค.
๊ทธ ๋ค์ ์์ฉ๊ฐ๋ฅํ ๋ฌด๊ฒ๊ฐ 4์ผ ๋์ด๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก i=2 ์ผ ๋ ๋ด์ ์ ์๋ ๊ฒ์ ๋ฐ๊ฒฌํ ์ ์๋ค.
์ฌ๊ธฐ์ ์ค์ํ ํฌ์ธํธ ํ๋.
i = 1๋ถํฐ ํ์ํ ๋, i = 1 ์ผ ๋์๋ (6, 13) ์ผ๋ก ์ฃผํฉ์ ๋ฐ์ค์ ์๋ ์นธ์ ๋ค์ด๊ฐ ์ ์๋ค. ์ฆ, ํ์ํ๊ธฐ ์ ์ ํด๋น ๊ฐ์ ๋ํ์ฌ ์ด์ i๊ฐ์ ๋ํ dp์ ๋ฉ๋ชจ์ด์ ์ด์ ๋์ด์๋ ๊ฐ์ ๊ฐ๊ณ ์์ผํ๋ค.
ํ์ฌ ์์ฉ๊ฐ๋ฅํ ๋ฌด๊ฒ๊ฐ 4๋ผ๋ฉด i ํ์ ์ ์ ๋จผ์ ์ด์ i์ ๋ํ ๊ฐ์ ๊ฐ๊ณ ์์ผํ๋๋ฐ, i = 0์ธ ๊ฒฝ์ฐ๋ ์ฃผ์ด์ง์ง ์๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ 0์ด ์ฑ์์ง๋ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๋ ํ, i = 2 ๋ถํฐ๋ 8์ ๋ฃ๋ ๊ฒ์ด ์ต๋ ๊ฐ์น์ด๋ฏ๋ก 8์ด ์ฐจ์งํ๊ฒ ๋ ๊ฒ์ด๋ค.
๋ค์ ์ค๋ ๋๊ฐ์ ๋ฐฉ์์ผ๋ก ์ฑ์ด๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก i = 1, 2, 3๋ฒ์งธ ์ด์์๋ ์ด์ ๋ฌด๊ฒ์ ๊ฐ์ ๊ฐ๊ณ ์๊ฒ ๋ ๊ฒ์ด๊ณ , i = 4 ์ผ ๋ ์๋ก์ด ๊ฐ์ด ๋ฃ์ด์ง ๊ฒ์ด๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก,,,
๊ทธ๋ฆฌ๊ณ 7๋ฒ์งธ๊ฐ ๊ฐ์ฅ ์ค์ํ๋ค. ์ฌ์ค ์ด์ ๊น์ง๋ ๋ ๊ฐ ์ด์์ ์กฐํฉ์ผ๋ก๋ ๊ตฌ์ฑํ ์๊ฐ ์์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ ๋์ด๊ฐ์ง๋ง, 7๋ถํฐ๋ ๋ค๋ฅด๋ค. ํ ๋ฒ ๋ณด๋๋ก ํ์.
๋จผ์ ์ด์ ๊ณผ์ ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ด์ ์ i๊ฐ์ ๋ํ์ฌ ๊ฐ์ ๊ฐ๊ณ ์จ๋ค. ๋ค๋ง, i = 0 ์ผ ๋๋ ์ฃผ์ด์ง ๋ฐฐ์ด ๋ฒ์ ๋ฐ์ด๊ธฐ ๋๋ฌธ์ 0์ด ๋๋ค.
๊ทธ๋ฆฌ๊ณ i=1 ์ผ ๋ ํ์์ ํด๋ณด์. (W1, V1) ์ (6, 13)์ด์๋ค. ๊ทธ๋ผ ๋ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ๊ตฌ์ฑํ ์ ์๋ค. ๋ฌด๊ฒ๊ฐ 7์ธ ๋ฌผ๊ฑด ๋๋ (๋ฌด๊ฒ๊ฐ 6์ธ ๋ฌผ๊ฑด + ๋ฌด๊ฒ๊ฐ 1์ธ ๋ฌผ๊ฑด) ์ ์กฐํฉ์ ๊ฐ์ ์ ์๋ค.
์ฆ, dp[7 - W[1]] ์ธ dp[1]์ ์ด์ i๊ฐ(i=0) ์ ๋ํ ๊ฐ + W[1]์ ๊ฐ์น = 13๊ณผ dp[7]i=0 = 0์ ๋น๊ตํ๋ ๊ฒ์ด๋ค. ์ฆ, 13์ด 0๋ณด๋ค ํฌ๊ธฐ ๋๋ฌธ์ 13์ด ์ ์ฅ๋๋ค.
ํ๋ง๋๋ก ๋ถํ ํ์ฌ ๋ฌด๊ฒ๊ฐ 6์ธ ๋ฌผ๊ฑด(๊ฐ์น=13)๊ณผ ๋ฌด๊ฒ๊ฐ 1(๊ฐ์น=์กด์ฌX)์ธ ๊ฐ์น์ ํฉ๊ณผ
๋ฌด๊ฒ๊ฐ 0์ธ ๋ฌผ๊ฑด์ ๊ฐ์น๋ฅผ ๋น๊ตํ๋ ๊ฒ์ด๋ค.
๋ค์ i = 2์ผ ๋์ด๋ค.
i = 2 ๋ (4, 8) ์ด๋ค. ์ผ๋จ ์ด์ i๊ฐ์ธ 13์ ๊ฐ๊ณ ์จ๋ค. ๊ทธ๋ฆฌ๊ณ (7 - W[2]) ๋ฌด๊ฒ์ ๋ํ ์ด์ i๊ฐ, ์ฆ (7 - 4) = 3์ด๊ณ , 3์ด๋ผ๋ ๋ฌด๊ฒ์ ๋์๋๋ i = 1 ์ผ ๋์ ๊ฐ(๋นจ๊ฐ์ ๋ฐ์ค)์ 0์ด๋ค . ์ด ๋์ ํฉํ๋ฉด 8์ด ๋๊ณ , 8๊ณผ 13 ์ค ์ต๋๊ฐ์ 13์ด๋ฏ๋ก 13์ด ์ ์ฅ๋๋ค.
i = 3 ์ผ ๋๋ ๋ง์ฐฌ๊ฐ์ง๋ค. ๋จผ์ ์ด์ dp[7] ์ผ ๋์ i=2์ ๊ฐ 13์ ๊ฐ๊ณ ์จ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ์กฐํฉ๋ฐฉ๋ฒ์ ํ์ํ๊ธฐ ์ํด ํ์ฌ i = 3 ์ (3, 6)์ด๊ณ ๊ฐ์น๋ 6์ด๋ค. ๊ทธ๋ฆฌ๊ณ (7 - W[3]) = (7 - 3) = 4์ด๊ณ 4์ ๋์๋๋ i = 2์ ๊ฐ์น๋ ๊ฐ์น๋ 8์ด๋ค. ์ฆ, 6 + 8 = 14๊ฐ ๋๊ณ , ์ด์ i๊ฐ๋ณด๋ค ํฐ ๊ฐ์ด๋ฏ๋ก ์ต๋๊ฐ 14๊ฐ ์ ์ฅ๋๋ค. ์ฆ, ์๋์ ๊ฐ๋ค.
๊ทธ ๋ค์๋ ๋ง์ฐฌ๊ฐ์ง๋ค. ์ด์ ํ์ ๊ฐ 14(dp[7]i=3) ๊ณผ (7 - W[4]) = 2i=3 ๊ฐ์ธ 0๊ณผ V[4] ์ธ 12์ ํฉ 12๋ฅผ ๋น๊ตํ๋ฉด 14๊ฐ ํฌ๋ฏ๋ก 14๊ฐ ์ ์ฅ๋๋ค.
i = 4 ์ผ ๋ ๊ฐ์น๋ (5, 12) ๋ก 12 ์ด๊ณ , (7 - W[5]) = 2๋ก, 2์ ๋์ํ๋ ๋ฌด๊ฒ๋ 0์ด๋ค. ์ฆ ํฉ์ 12์ด์ธ๋ฐ, ์ด์ ๊ฐ 14 ๋ณด๋ค ์๊ธฐ ๋๋ฌธ์ 12๊ฐ ์๋ 14๊ฐ ์ ์ฅ๋๋ ๊ฒ์ด๋ค.
์ด๋ฌํ ๋ ๊ฐ์ง ์๋ฆฌ๋ก ์ ํ์์ ๋ง๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ง๋ค ์ ์๋ค.
f ๋ ํจ์ f, k๋ ์ ํ์์ dp, W๋ ์ ๋ ฅ์ผ๋ก ์ฃผ์ด์ง๋ ๋ฌด๊ฒ, V๋ ์ ๋ ฅ์ผ๋ก ์ฃผ์ด์ง๋ ๊ฐ์น์ด๋ค.
์ด๋ฅผ ํ ๋๋ก ์ฌ๊ท๋ฌธ(Top-Down ๋ฐฉ์)์ ๋ง๋ค ์ ์๋ค.
static int knapsack(int i, int k) {
// i๊ฐ 0๋ฏธ๋ง, ์ฆ ๋ฒ์ ๋ฐ์ด ๋๋ค๋ฉด
if (i < 0)
return 0;
// ํ์ํ์ง ์์ ์์น๋ผ๋ฉด?
if (dp[i][k] == null) {
// ํ์ฌ ๋ฌผ๊ฑด(i)์ ์ถ๊ฐ๋ก ๋ชป๋ด๋ ๊ฒฝ์ฐ (์ด์ i๊ฐ ํ์)
if(W[i] > k) {
dp[i][k] = knapsack(i - 1, k);
}
// ํ์ฌ ๋ฌผ๊ฑด(i)์ ๋ด์ ์ ์๋ ๊ฒฝ์ฐ
else if (W[i] <= k) {
// ์ด์ i๊ฐ๊ณผ ์ด์ i๊ฐ์ ๋ํ k-W[i]์ ๊ฐ + ํ์ฌ ๊ฐ์น(V[i])์ค ํฐ ๊ฐ์ ์ ์ฅ
dp[i][k] = Math.max(knapsack(i - 1, k), knapsack(i - 1, k - W[i]) + V[i]);
}
}
return dp[i][k];
}
W์ V ๋ฐฐ์ด์ N๊ธธ์ด๋ก ์ธ๋ฑ์ค๊ฐ 0 ๋ถํฐ ์์ํ๊ธฐ ๋๋ฌธ์ ์์ i=0์ผ ๋๋ฅผ ์ฝ๊ฐ ์์ ํ์ฌ i < 0์ผ๋ก ๊ณ ์ณ์ค๋ค. ๋ํ f(i - 1, k) ์ ๊ฒฝ์ฐ ๊ฒฐ๊ตญ ์ต์ํ ํ ๋ฒ์ ํ์ํด์ผํ๊ธฐ ๋๋ฌธ์ ์ ์ ์ ์ผ๋ก ์ด์ i๊ฐ์ ๋ํ์ฌ ์ฌ๊ทํ์์ ํด์ฃผ์ด์ผ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ดํดํ๊ธฐ ํธํ๊ฒ else if() ๋ฅผ ์ผ์ง๋ง, ๊ทธ๋ฌ์ง ์๊ณ ๊ทธ๋ฅ else{} ๋ก ๋ฐ๊ฟ์ฃผ์ด๋ ๋ฌด๋ฐฉํ๋ค.
์ด๋ฅผ ์ญ์ผ๋ก Bottom-Up ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= K; j++) {
// i๋ฒ์งธ ๋ฌด๊ฒ๋ฅผ ๋ ๋ด์ ์ ์๋ ๊ฒฝ์ฐ
if(W[i] > j) {
dp[i][j] = dp[i - 1][j];
}
// i๋ฒ์งธ ๋ฌด๊ฒ๋ฅผ ๋ ๋ด์ ์ ์๋ ๊ฒฝ์ฐ
else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - W[i]] + V[i]);
}
}
}
์ด ๊ฒฝ์ฐ ํ์ ์ธ๋ฑ์ค๋ถํฐ ์์ํ๊ธฐ ๋๋ฌธ์ i-1 ์ ๋ํ์ฌ ์์นซ ์ธ๋ฑ์ค ๋ฒ์ ๋ฐ์ ์ฐธ์กฐํ๊ฒ ๋ ์ ์๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ W, N ์ ๊ฐ๊ฐ [N+1] ์ฌ์ด์ฆ๋ก ์ ์ธํด์ฃผ์ด์ผ ํ๋ค.
๊ทธ๋ฆฌ๊ณ Bottom-Up ๋ฐฉ์์ ํน์ฑ์ ์์ ๊ฒ๋ถํฐ ๋ง์ถฐ๋๊ฐ๊ธฐ ๋๋ฌธ์ dp๋ฐฐ์ด์ 2์ฐจ์์ด ์๋๋ผ 1์ฐจ์์ผ๋ก ์์ฑํ๊ณ ์ค๋ณตํ์์ ํผํด๊ฐ๋ ๋ฐฉ์์ผ๋ก ๋ฐ๊ฟ ์ ์๋ค. ์ด๋ป๊ฒ? ์๊ฐํด๋ณด์. ์ฐ๋ฆฌ๊ฐ ๊ฐ ํ์์ ๊ฒฝ์ฐ i๋ฒ์งธ ๋ฌผ๊ฑด์ ๋ํ์ฌ W[i]์ ํฉ์ด K๋ฅผ ๋๊ฒจ์๋ ์๋๋ค. ์ด๋ ๊ฑฐ๊พธ๋ก ๋งํ๋ฉด K(์ต๋๋ฌด๊ฒ) - ๋์ ๋ W๊ฐ์ด 0๋ณด๋ค ์ปค์ผํ๋ค๋ ์๋ฏธ๋ค. ์ฆ, ๋ถํ์ํ๊ฒ 1๋ถํฐ K๊น์ง ํ์ํ๋ ๊ฒ์ด ์๋๋ผ K-W[i] ์ ๋ํ์ฌ 0๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ ๋ ๊น์ง๋ง ํ์ํจ์ผ๋ก ๋ถํ์ํ ํ์์ ์ค์ผ ์ ์๊ณ , ์ค๋ณต ์นด์ดํธ ๋ํ ํผํ ์ ์๋ค.
for (int i = 1; i <= N; i++) {
// K๋ถํฐ ํ์ํ์ฌ ๋ด์ ์ ์๋ ๋ฌด๊ฒ ํ๊ณ์น๊ฐ ๋์ง ์์ ๋๊น์ง ๋ฐ๋ณต
for (int j = K; j - W[i] >= 0; j--) {
dp[j] = Math.max(dp[j], dp[j - W[i]] + value[i]);
}
}
Bottom-Up ์ฒซ ๋ฒ์งธ ์๊ณ ๋ฆฌ์ฆ๋ณด๋ค ํจ์ฌ ๊ฐ๊ฒฐํ๋ค. ๋ฐ๋ณต๋ฌธ ์กฐ๊ฑด์ ์์ฒด๋ฅผ j-W[i] >= 0 ์ผ๋ก ์ ์ธํด์ฃผ๋ฉด์ i๋ฒ์งธ ๋ฌผ๊ฑด์ ๋ํด ๋ฃ์ ์ ์๋ ๊ฒฝ์ฐ์ ํ์ ํ์ฌ ํ์ํ๋ ๊ฒ์ด๋ค.
์ฌ๊ท๋ก๋ ์์๊ฐ์ด ํ๊ธฐ ํ๋ค๋ค. Top-Down ๋ฐฉ์ ์์ฒด๊ฐ ํฐ ๊ทธ๋ฆผ์์ ์์ ๋จ์๋ก ์ชผ๊ฐ๋ค์ด๊ฐ๋ ๊ฒ์ด๋ผ ๋ค๋ฅธ ๋จ์์์ dp์ ๋ํด ์ฐธ์กฐ๋ฅผ ํ ๋ ์์นซ ๋ถ์์ ํ dp๊ฐ์ ์ฐธ์กฐํ์ฌ ์๋ฑํ ๊ฐ์ด ์ต๋๊ฐ์ด ๋ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ฆ, ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ธ๋ฃจํธํฌ์ค(Brute Force)๋ก ํด์ผํ๋๋ฐ ์ด๋ ๋ฉ๋ชจ์ด์ ์ด์ ์ ํ์ง ์๊ธฐ ๋๋ฌธ์ ๋น์ฐ ์๊ฐ ๋ณต์ก๋๊ฐ O(N2) ์ด ๋๊ณ , ์ด ๋ฌธ์ ์์๋ 100% ์๊ฐ์ด๊ณผ๋ฅผ ๋ฐ๊ฒ ๋๋ค.
ํ์ด ๋ฐ ์ฝ๋
- ๋ฐฉ๋ฒ 1 : [Top-Down]
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main {
static Integer[][] dp;
static int[] W; // weight
static int[] V; // value
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int N = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
W = new int[N];
V = new int[N];
dp = new Integer[N][K + 1];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine(), " ");
W[i] = Integer.parseInt(st.nextToken());
V[i] = Integer.parseInt(st.nextToken());
}
System.out.println(knapsack(N - 1, K));
}
static int knapsack(int i, int k) {
// i๊ฐ 0๋ฏธ๋ง, ์ฆ ๋ฒ์ ๋ฐ์ด ๋๋ค๋ฉด
if (i < 0)
return 0;
// ํ์ํ์ง ์์ ์์น๋ผ๋ฉด?
if (dp[i][k] == null) {
// ํ์ฌ ๋ฌผ๊ฑด(i)์ ์ถ๊ฐ๋ก ๋ชป๋ด๋ ๊ฒฝ์ฐ (์ด์ i๊ฐ ํ์)
if(W[i] > k) {
dp[i][k] = knapsack(i - 1, k);
}
// ํ์ฌ ๋ฌผ๊ฑด(i)์ ๋ด์ ์ ์๋ ๊ฒฝ์ฐ
else {
// ์ด์ i๊ฐ๊ณผ ์ด์ i๊ฐ์ ๋ํ k-W[i]์ ๊ฐ + ํ์ฌ ๊ฐ์น(V[i])์ค ํฐ ๊ฐ์ ์ ์ฅ
dp[i][k] = Math.max(knapsack(i - 1, k), knapsack(i - 1, k - W[i]) + V[i]);
}
}
return dp[i][k];
}
}
- ๋ฐฉ๋ฒ 2 : [Bottom-Up 1]
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int N = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
int[] W = new int[N + 1]; // ๋ฌด๊ฒ
int[] V = new int[N + 1]; // ๊ฐ์น
int[][] dp = new int[N + 1][K + 1];
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine(), " ");
W[i] = Integer.parseInt(st.nextToken());
V[i] = Integer.parseInt(st.nextToken());
}
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= K; j++) {
// i๋ฒ์งธ ๋ฌด๊ฒ๋ฅผ ๋ ๋ด์ ์ ์๋ ๊ฒฝ์ฐ
if(W[i] > j) {
dp[i][j] = dp[i - 1][j];
}
// i๋ฒ์งธ ๋ฌด๊ฒ๋ฅผ ๋ ๋ด์ ์ ์๋ ๊ฒฝ์ฐ
else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - W[i]] + V[i]);
}
}
}
System.out.println(dp[N][K]);
}
}
- ๋ฐฉ๋ฒ 3 : [Bottom-Up 2]
๋ ๋ฒ์งธ Bottom-Up ๋ฐฉ์์ด๋ค. ๋ฌด๊ฒ๋ฅผ ๋ ๋ด์ ์ ์๋์ง ์ฌ๋ถ๋ฅผ ์กฐ๊ฑด์ผ์ ๋ฐ๋ณต๋ฌธ์ผ๋ก ๊ตฌํํ๊ธฐ ๋๋ฌธ์ dp[] ๋ฐฐ์ด์ 1์ฐจ์์ผ๋ก ์ธ ์ ์๊ณ ๋ถํ์ํ ํ์์ ํ์ง ์๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ๊ฐ์ ์ ๋์์ด ๋ ๊ฒ์ด๋ค.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int N = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
int[] W = new int[N + 1]; // ๋ฌด๊ฒ
int[] V = new int[N + 1]; // ๊ฐ์น
int[] dp = new int[K + 1];
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine(), " ");
W[i] = Integer.parseInt(st.nextToken());
V[i] = Integer.parseInt(st.nextToken());
}
for (int i = 1; i <= N; i++) {
// K๋ถํฐ ํ์ํ์ฌ ๋ด์ ์ ์๋ ๋ฌด๊ฒ ํ๊ณ์น๊ฐ ๋์ง ์์ ๋๊น์ง ๋ฐ๋ณต
for (int j = K; j - W[i] >= 0; j--) {
dp[j] = Math.max(dp[j], dp[j - W[i]] + V[i]);
}
}
System.out.println(dp[K]);
}
}