๋
์ ์๊ณ ๋ฆฌ์ฆ์ ์ ๋ช
ํ dp ๋ฌธ์ ์ค ํ๋์ด๋ค.
๋
์ ์๊ณ ๋ฆฌ์ฆ์ ๋ ๊ฐ์ง๋ก ๋๋๋ค.
(์ง ์ธ๊ธฐ ๋ฌธ์ ๋ dp๋ก ํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค !!)
Fraction Knapsack
Fraction Knapsack ๋ฌธ์ ๋ ๋ฌผ๊ฑด์ ๊ฐ๊ฒฉ์ ๋ฌด๊ฒ๋ก ๋๋์ด ๋ฌด๊ฒ ๋๋น ๊ฐ๊ฒฉ์ด ๋น์ผ ์์๋ก ๋ฌผ๊ฑด์ ์ ๋ ฌํด์ ๋ฃ์ผ๋ฉด ์ฝ๊ฒ ํด๊ฒฐํ ์ ์๋ค.
๋จ์ ๋ฐฐ๋ญ์ด ๊ฐ๋นํ ์ ์๋ ๋ฌด๊ฒ๋ณด๋ค ๋ฌผ๊ฑด์ ๋ฌด๊ฒ๊ฐ ๋ง์ด ๋๊ฐ๋ฉด ์๋ผ์ ๋ฃ์ผ๋ฉด ๋๋ค.
= greedy๋ก ํด๊ฒฐ ๊ฐ๋ฅ!
0-1 Knapsack
0-1 Knapsack ๋ฌธ์ ๋ ๋ฌผ๊ฑด์ ์๋ฅผ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฌผ๊ฑด, ๋ฌผ๊ฑด์ ๋ฌด๊ฒ, ๋ฌผ๊ฑด์ ๊ฐ๊ฒฉ, ๋ฐฐ๋ญ์ ๋จ์ ์ฉ๋์ ๋ชจ๋ ๊ณ ๋ คํด์ผ ํ๋ค.
= dp๋ก ํด๊ฒฐ ๊ฐ๋ฅ!
๊ฐ๋ฐฉ์ ๋ด์ ์ ์๋ ๋ฌด๊ฒ์ ํ๊ณ๊ฐ ์๊ณ , ๊ฐ ๋ฌผ๊ฑด์ ๊ฐ์น๊ฐ ์ ํด์ ธ์๋ค.
๐ ์ธ๋ป๋ณด๋ฉด ๊ทธ๋ฆฌ๋ ์๊ณ ๋ฆฌ์ฆ๊ณผ ๋น์ทํด(์ต์ ์ ํด๋ฅผ ๊ตฌํ๊ธฐ) ๋ณด์ด์ง๋ง, ์ต์ ์ ํด๊ฐ ๋์ค์ง ์์ ๋๋ ์๋ค.
์์ ) ๊ฐ๋ฐฉ์ 15kg๊น์ง ๋ด์ ์ ์๊ณ , ์ธ๊ฐ์ง ๋ฌผ๊ฑด์ด ์๋ค. ์ด๋ ๊ฐ์น๋ฅผ ์ต๋๋ก ๊ฐ์ง๋ ค๋ฉด ์ด๋ค ๋ฌผ๊ฑด์ ๋ด์์ผํ ๊น?
[๋ฌผ๊ฑด A] ๊ฐ์น: 10, ๋ฌด๊ฒ: 13kg
[๋ฌผ๊ฑด B] ๊ฐ์น: 6, ๋ฌด๊ฒ: 6kg
[๋ฌผ๊ฑด C] ๊ฐ์น: 5, ๋ฌด๊ฒ: 6kg
๊ทธ๋ฆฌ๋ ์๊ณ ๋ฆฌ์ฆ
๊ฐ์น๋ฅผ ์ต๋๋ก ๊ฐ๋๋ก ๊ทธ๋๊ทธ๋ ์ต์ ์ ์ ํ์ ํ๊ธฐ๋๋ฌธ์ ๋ฌผ๊ฑด A๋ฅผ ๋ด๊ณ ๋์ด ๋๋ค.
์ ๋ต
๋ฌผ๊ฑด A๋ฅผ ๋ด์ง ์๊ณ , B์ C๋ฅผ ๋ด๋๋ค.
์คํ๋ ค ํน์ ๋ฌผ๊ฑด์ ๋ด์ง ์์์ ๋๊ฐ ์ต์ ์ ์ ํ์ผ ์ ์์์ ๊ณ ๋ คํด์ฃผ๋ ๊ฒ์ด ๋ ์ ์๊ณ ๋ฆฌ์ฆ์ ํต์ฌ์ธ ๊ฒ ๊ฐ๋ค.
โฝ ๋ ์ ์๊ณ ๋ฆฌ์ฆ์ ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ (DP)๋ฅผ ์ด์ฉํ๋ฉด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค.
x์ถ์๋ ๊ฐ๋ฐฉ 1~k๊ฐ์ ๋ฌด๊ฒ, y์ถ์๋ ๋ฌผ๊ฑด์ ๊ฐฏ์ n๋งํผ์ ๋ฐฐ์ด์ ๋ง๋ค์ด์ค๋ค.
ํ์ ์ฐจ๋ก๋๋ก ๋๋ฉด์ ์๊ณ ๋ฆฌ์ฆ์ ์ํํด ์ค ๊ฒ์ธ๋ฐ,
ํ์ฌ ๋ฌผ๊ฑด(i)์ด ํด๋น ์ด์ ๋ฌด๊ฒ๋ณด๋ค ํฌ๋ฉด, ๋ด์ ์ ์๋ ๋ฌผ๊ฑด์ด๋ฏ๋ก [์ด์ ๋ฌผ๊ฑด][ํ์ฌ๋ฌด๊ฒ] (knapsack[i-1][j]) ๊ทธ๋๋ก ์ ์ฉํด์ค๋ค.
ํ์ฌ ๋ฌผ๊ฑด์ด ํด๋น ์ด์ ๋ฌด๊ฒ๋ณด๋ค ๊ฐ๊ฑฐ๋ ์์ผ๋ฉด ๋ด์ ์ ์์ผ๋ฏ๋ก, ๋ฃ์ด์คฌ์ ๋๋ฅผ ๊ณ์ฐํ๋ค. ํ์ฌ ๋ฌผ๊ฑด + [์ด์ ๋ฌผ๊ฑด][j-ํ์ฌ๋ฌผ๊ฑด] (weight + knapsack[i-1][j-weight])
์์์ ๊ตฌํ ๋ฌด๊ฒ์ [์ด์ ๋ฌผ๊ฑด][ํ์ฌ๋ฌด๊ฒ]๋ฅผ ๋น๊ตํด์ ๊ทธ ์ค ๋ ํฐ ๊ฐ์ ์ฑํํ๋ค.
๊ฒฐ๊ตญ knapsack[n][k]๋ k๋ฌด๊ฒ์ผ ๋ ์ต๋๊ฐ(์ต๋ ๊ฐ์น)์ ๊ฐ๋ฆฌํจ๋ค.
๊ฒฐ๊ตญ ์์์ผ๋ก ํํํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
knapsack[i][j] = max(ํ์ฌ ๋ฌผ๊ฑด ๊ฐ์น + knapsack[์ด์ ๋ฌผ๊ฑด][ํ์ฌ ๊ฐ๋ฐฉ ๋ฌด๊ฒ - ํ์ฌ ๋ฌผ๊ฑด ๋ฌด๊ฒ], knapsack[์ด์ ๋ฌผ๊ฑด][ํ์ฌ ๊ฐ๋ฐฉ ๋ฌด๊ฒ])
knapsack[i][j] = max(value + knapsack[i - 1][j - weight], knapsack[i - 1][j])
์ด ๋ฌธ์ ์ ์ ๋ต์ dp[N][K]์ ๋ค์ด์๋ค.
์ด์ dp[i][j]์ ์ ํ์์ ๋ํ๋ผ ์ ์๋ค. ์ด ๋ฌธ์ ๋ dp[i][j]์ ๊ฐ์ ์ฐจ๋ก๋๋ก ์ฑ์๋๊ฐ์ผ ํ๋ค.
dp[i][j]์๋ dp[i-1][j]์ dp[i-1][j-w] + v์ ๊ฐ ์ค ๋ ํฐ ๊ฐ์ด ๋ค์ด๊ฐ๊ฒ ๋๋ค.
1) i๊ฐ ํ์ฌ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ w๋ณด๋ค ์์ ๋
- ํ์ฌ ๋ฌผ๊ฑด์ ๋ด์ ์ ์์ผ๋ฏ๋ก ์ด์ ์ ๊ฐ์ ๋ณต์ฌํ๋ค.
dp[i][j] = dp[i][j-1]
2) i๊ฐ ํ์ฌ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ w์ ๊ฐ๊ฑฐ๋ ํด ๋
- ํ์ฌ ๋ฌผ๊ฑด์ ๋ด์ ์ ์๋ค.
- ๋ฌผ๊ฑด์ ๋ด์์ ๋์ ๋ด์ง ์์์ ๋์ ๊ฐ์น๋ฅผ ๋น๊ตํด์ค ๋ค ๋ ํฐ ๊ฐ์ ํ ๋นํด์ค๋ค.
- ํ์ฌ ๋ฌผ๊ฑด์ ๊ฐ์น๋ v ์ด๋ค.
dp[i][j] = max( dp[i][j-1] , dp[i-w][j-1] + v)
๋ฌผ๊ฑด์ ๋ฐฐ๋ญ์ ๋ด์ ๋,
1. ํ์ฌ ๋ฐฐ๋ญ์ ํ์ฉ ๋ฌด๊ฒ๋ณด๋ค ๋ฃ์ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ๊ฐ ๋ ํฌ๋ค๋ฉด ๋ฃ์ง ์๋๋ค.
2. ํ์ฌ ๋ฌผ๊ฑด์ ๋ฃ์ ์ ์๋ค๋ฉด, ๋ค์ ์ค ๋ ๋์ ๊ฐ์น๋ฅผ ์ ํํ๋ค.
์ ๊ณผ์ ์ ์์ผ๋ก ๋ํ๋ด๋ฉด,
ํ์ฌ ๋ด์ ๋ฌผ๊ฑด์ ์ธ๋ฑ์ค๋ฅผ i, ํ์ฌ ๊ฐ๋ฐฉ ํ์ฉ ๋ฌด๊ฒ๊ฐ j, ํ์ฌ ๋ด์ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ weight, ๊ฐ์น value๋ผ๊ณ ํ๋ฉด
j < weight: dp[i][j] = dp[i-1][j]
dp[i][j] = max(dp[i-1][j-weight] + value, dp[i-1][j])
2-1 ๊ณผ์ ์์ ํ์ฌ ๋ฃ์ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ๋งํผ ๋ฐฐ๋ญ์์ ๋บ๋ค๊ณ ํ ๋ถ๋ถ์ ์๋ฌธ์ ์ด ๋ค ์ ์๋ค.
ํ์ง๋ง ํ์ฌ ๋ฃ์ ๋ฌผ๊ฑด์ ๋ฌด๊ฒ๋งํผ ๋บ ๋ฐฐ๋ญ์๋ ๊ทธ ๋ฌด๊ฒ์ ๋ฐฐ๋ญ์ด ๊ฐ์ง๋ ์ต๋ ๊ฐ์น๊ฐ ์ ์ฅ๋์ด ์๋ค. ๊ทธ๋์ ์๊ด์๋ค.
โฝ ๋ฌผ๊ฑด์ ์ต๋ ๊ฐ์น๋ dp[๊ฐ๋ฐฉ ํฌ๊ธฐ][๋ฌผ๊ฑด์ ๊ฐ์]๋ก ๊ตฌํ ์ ์๋ค !
import sys
N, K = map(int, input().split())
stuff = [[0,0]]
knapsack = [[0 for _ in range(K + 1)] for _ in range(N + 1)]
for _ in range(N):
stuff.append(list(map(int, input().split())))
#๋
์ ๋ฌธ์ ํ์ด
for i in range(1, N + 1):
for j in range(1, K + 1):
weight = stuff[i][0]
value = stuff[i][1]
if j < weight:
knapsack[i][j] = knapsack[i - 1][j] #weight๋ณด๋ค ์์ผ๋ฉด ์์ ๊ฐ์ ๊ทธ๋๋ก ๊ฐ์ ธ์จ๋ค
else:
knapsack[i][j] = max(value + knapsack[i - 1][j - weight], knapsack[i - 1][j])
print(knapsack[N][K])
๐ป ๋ค์ด๋๋ฏน ํ๋ก๊ทธ๋๋ฐ์ ์์ ๋จ๊ณ๋ถํฐ ์ฌ๋ผ๊ฐ๊ธฐ ๋๋ฌธ์ ๋ณด์์ด ํ๊ฐ๋ง ์์ ๋๋ถํฐ ์ฒ์ฒํ ์ฌ๋ผ๊ฐ๊ธฐ. ๋ฌธ์ ๋ฅผ ์๊ฐํํ ์ ์์ด์ผ ํ๋ค !!
ํด๋น ๋ฌธ์ ๋ฅผ dp 1์ฐจ์ ๋ฐฐ์ด๋ก ํด๊ฒฐํ ์ ์๋ค. (์ต์ ํ)
์ด์ dp[j]๊ฐ ๊ฐ์ง๋ ๊ฐ์ ์๋ฏธ๋ฅผ ์์๋ณด์
dp[j] : ๊ฐ๋ฐฉ์ j๋ผ๋ ๋ฌด๊ฒ(weight)๊น์ง(์ต๋ ๋ฌด๊ฒ) ๋ด์ ์ ์์ ๋ ์ด๋ ์ด ๊ฐ๋ฐฉ์ด ๊ฐ์ง ์ ์๋ ์ต๋ ๊ฐ์น(๋ณด์)๋ฅผ ์๋ฏธํ๋ค. (j๋ ๊ฐ๋ฐฉ ๋ฌด๊ฒ์ ํ๊ณ)
์ด์ ์์ฃผ ์์ ๋จ์๋ถํฐ ์๊ฐํด๋ณด์.
๋ณด์์ ๋ฌด๊ฒ, ๊ฐ์น๊ฐ 5,12์ผ ๋๋ฅผ ์๊ฐํด๋ณด๋ฉด dp[j]์์ j๋ 5๋ถํฐ ๊ฐ์ ๋ฃ์ ์ ์๋ค.
dp[j-w] + v
์ฆ ํ์ฌ ๋ณด์(5,12)๋ฅผ ๋ด๋๋ค๊ณ ๊ฐ์ ์ ํ๊ธฐ ๋๋ฌธ์ -5๋ฅผ ํด์ค์ผ ํ๋ค. + ํ์ฌ ๋ณด์์ ๊ฐ์น 12๋ฅผ ๋ํด์ค๋ค. (๋ด๋๋ค๊ณ ๊ฐ์ ์ ํ๊ธฐ ๋๋ฌธ !)
ํ์นธ ๋ ๊ฐ์ dp[j ==6]์ ๋ํด์ ์๊ฐํด๋ณด์.
(5,12) ๋ณด์์ ๋ด์ ์ ์์ผ๋ฏ๋ก d[j-w] + 12๋ฅผ ์ ์ฉ๊ฐ๋ฅ!
๐ป ์ด์ ๊ฐ๋ฐฉ์ ์ต๋ ๋ฌด๊ฒ j == 10์ด ๋ ๋๊ฐ ์ค์
dp[j-w] + v์ธ๋ฐ dp[5] + 12๋ก ํด์๋๋ค. ๊ทผ๋ฐ ์ด๋ฏธ dp[5]์ ๊ฐ์ ๊ตฌํด๋จ๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด ๊ฐ๋ณด๋ค ์ปค์ ๊ฐฑ์ ๋๋ค ! ์ด๋ฐ์์ผ๋ก ๊ฐ ๋ณด์๋ค์ ํ๋์ฉ ์ ์ฉํ๋ฉด์ ๊ฐ๋ฐฉ์ ์ต๋ ๋ฌด๊ฒ์ผ ๋์ ์ต๋ ๊ฐ์น๋ฅผ ์ ์ฅํด๋๊ฐ๋ฉด ๋๋ค.
๋น๊ต
๋ฅผ ํ๊ฒ ๋๋ค. ํด๋น ๋ณด์์ j == 3 ์ผ ๋๋ถํฐ (๊ฐ๋ฐฉ์ด ๋ด์ ์ ์๋ ์ต๋ ๋ฌด๊ฒ๊ฐ 3์ผ ๋๋ถํฐ) ์ ์ฉํ ์ ์๋ค.
๊ทผ๋ฐ ์ด์ j == 5์ผ๋...
dp[5 - 3] + 8์ ๊ทธ๋๋ก ์ ์ฉํ ๊ฒ์ธ๊ฐ ? NO
๊ฒฐ๊ตญ ๊ธฐ์กด ๊ฐ๋ณด๋ค ๋ ํฐ ๊ฐ์น๋ฅผ ๊ฐ์ง๋ ๊ฐ์ด ๋์์ผ ๊ฐฑ์ ์ด ๋๋๊ฑฐ์ผ !
import sys
sys.stdin = open("input.text", "rt")
input = sys.stdin.readline
sys.setrecursionlimit(10**6)
data = []
n, limit = map(int, input().split()) #๋ณด์ ์ข
๋ฅ, ๋ฌด๊ฒ ํ๊ณ๊ฐ
for _ in range(n):
a,b = map(int, input().split())
data.append((a,b)) #๋ฌด๊ฒ, ๊ฐ์น
data.insert(0,(0,0)) #0๋ฒ ์ธ๋ฑ์ค ์ฌ์ฉ์ํจ
dp = [[0] * (limit+1) for _ in range(n+1)]
for i in range(1,n+1):
for j in range(1,limit + 1):
weight = data[i][0] # ํ์ฌ ๋ฌผ๊ฑด ๋ฌด๊ฒ
value = data[i][1] # ํ์ฌ ๋ฌผ๊ฑด ๊ฐ์น
if j < weight: #ํ์ฌ ๋ฌผ๊ฑด ๋ด์ ์ ์์ผ๋ ์ด์ ๊บผ ๊ฐ์ ธ์์ผํจ
dp[i][j] = dp[i-1][j]
else: #ํ์ฌ ๋ฌผ๊ฑด ๋ด์ ์ ์์
dp[i][j] = max(dp[i-1][j-weight] + value, dp[i-1][j])
print(dp[n][limit])
๐ป ๋ ์ ์๊ณ ๋ฆฌ์ฆ ์ต์ ํ
import sys
sys.stdin = open("input.text", "rt")
input = sys.stdin.readline
sys.setrecursionlimit(10**6)
data = []
n, limit = map(int, input().split()) #๋ณด์ ์ข
๋ฅ, ๋ฌด๊ฒ ํ๊ณ๊ฐ
dp = [0] * (limit + 1)
for i in range(n):
w,v = map(int, input().split()) #๋ฌด๊ฒ, ๊ฐ์น
for j in range(w , limit + 1): #ํ์ฌ ์ ์ฉํ๊ณ ์ ํ๋ ๋ฌด๊ฒ๋ถํฐ ๋์์ผ์ง
#์ด๋ ๊ฒ ์ํ ๊ฑฐ๋ฉด if๋ฌธ์ผ๋ก ๋ฐ๋ก ์กฐ๊ฑด ๊ฑธ์ด์ผํด!
dp[j] = max(dp[j], dp[j-w] + v) #ํ์ฌ ๋ณด์์ ๊ฐ๋ฐฉ์ ๋ด์ ๊ฒ์ด๋ผ๊ณ ๊ฐ์ ํ ๊ฐ์ด dp[j-w] + v ์ด๋ค.
print(dp[limit])
dp ํ ์ด๋ธ์ 2์ฐจ์์์ 1์ฐจ์์ผ๋ก ์ค์ฌ์ ์ฌ์ฉํ ์ ์๋ค !
์๊ฐ์ด๊ณผ ์๋ ๊ฒ ๊ฐ์ผ๋ฉด ์ํ๋ ์๊ฐํ์.