[알고리즘] 개념 - Knapsack Problem (배낭 문제)

공혁준·2022년 4월 26일
0

알고리즘 개념

목록 보기
1/5
post-thumbnail

📌 알고리즘 - 배낭 문제 개념

배낭 문제란?

배낭에 담을 수 있는 무게의 최대값(KK)이 정해져 있을 때 일정한 가치(VV)와 무게(WW)를 가진 짐을 배낭에 넣을 때 가치의 합이 최대가 되도록 배낭에 넣을 짐을 찾는 문제이다.

배낭 문제는 짐을 쪼갤 수 있는 경우와 짐을 쪼갤 수 없는 경우로 나눌 수 있는데 짐을 쪼갤 수 있는 경우 그리디 알고리즘으로 해결 가능하며, 짐을 쪼갤 수 없는 경우 동적계획법으로 해결 가능하다.

완전 탐색

짐의 개수가 NN일 때 가능한 부분집합의 개수는 2N2^N개이다. 따라서 시간복잡도는 O(2N)O(2^N)이다.
⇒ 너무 느리다.

동적계획법

D[i,w]D[i,w] = 배낭의 무게 한도가 ww이고, 11부터 ii번째 짐까지 배낭에 넣을 수 있을 때 얻을 수 있는 최고 가치

DP식 D[i,w]D[i,w]를 위와 같이 정의했을 때 점화식은 아래와 같다.

D[i, w]={0if i=0 or w=0D[i1, w]if wWi<0max(D[i1, w],         D[i1, wWi]+Vi)elseD[i,\ w] = \begin{cases} 0 & \text{if }i = 0\text{ or } w = 0 \\ D[i - 1,\ w] & \text{if }w-W_i < 0 \\ max(D[i - 1,\ w], \\ \ \ \ \ \ \ \ \ \ D[i - 1,\ w - W_i] + V_i) & \text{else} \end{cases}

2중 반복문으로 구현하면 되고, 시간복잡도는 O(NW)O(NW)이다.

for (int i = 1; i <= N; i++) {
	for (int w = 0; w <= W; w++) {
		if (w - W[i] >= 0) {
			dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - W[i]] + V[i]);
		}
		else {
			dp[i][w] = dp[i - 1][w];
		}
	}
}
profile
몰입을 즐기는 개발자입니다.

0개의 댓글