Open seungriyou opened 6 months ago
https://leetcode.com/discuss/study-guide/1200320/Thief-with-a-knapsack-a-series-of-crimes.
0/1 Knapsack 유사 문제도 풀어보자. 2D -> 1D로 optimize 가능하다면 줄이는 연습까지!
Bounded 0/1 Knapsack problems
Unbounded 0/1 Knapsack problems
Approach
0/1 knapsack 문제이다. 단, knapsack의 capacity 내에서 담을 수 있는 물건의 최대 가치를 구하는 것이 아닌, capacity와 동일한 값의 total sum을 달성할 수 있는지 여부를 구해야 한다.
이때, knapsack의 capacity는 주어진
nums
의 총합의 절반이다.만약
nums
의 총합이 홀수라면 절반으로 나누어떨어지지 않으므로 빠르게False
를 리턴하자!Idea 1: 2D DP
다음과 같이 0/1 knapsack 상황을 정의할 수 있다.
sum(nums) // 2
dp[i][j]
= nums의 i번째 원소까지 봤을 때, 그 합이 j인 조합이 존재하는지 여부로 정의하고, 다음과 같은 로직으로 값을 채워나간다.i
번째 물건(=nums[i - 1]
)이 배낭의 임시 용량j
보다 같거나 작다면,i
번째 물건을 아예 넣을 수 없으므로i - 1
번째 물건까지 살펴본 결과를 그대로 반영해야 한다.i
번째 물건을 넣지 않는 경우와 넣는 경우 중 하나라도 가능한지 확인하면 된다.Idea 2: 1D DP (Space Optimized)
2D DP에서 이전 row(
dp[i - 1]
)의 값(dp[i - 1][j]
혹은dp[i - 1][j - nums[i - 1]]
)만 필요했으므로, 1D DP로 space-optimize가 가능하다.단,
dp[i - 1]
의[j]
혹은[j - nums[i - 1]]
와 같이 이전 인덱스를 확인해야하므로, 오른쪽 -> 왼쪽 순으로 순회해야 한다.또한,
j
를 순회할 때,dp
테이블을 그대로 재사용하기 때문에 현재 보고 있는 물건의 무게num
이상인 값까지만 순회해도 되므로 time 측면에서도 약간 optimize가 되지 않을까 싶다!Idea 3: 다른 풀이 방법
bit mask, DFS 등 다양한 방법으로도 풀 수 있는 듯.
이건 나중에 복습할 때 알아보자..
🔍 Knapsack Problem
0/1 Knapsack vs. Fractional Knapsack
Bounded vs. Unbounded
References
Complexity
O(n * sum)
O(n * sum)
/ (1D DP)O(sum)