2013. 12. 12. 18:34ㆍ알고리즘 문제풀기/DP
냅색 문제는 유명한 다이나믹 문제 중 하나이다.
가장 유치하지만 또 가장 많이 쓰이는 설명으로는,
한 가게에 도둑이 들었다. 도둑이 훔치고 싶은 물건들은 다 각각의 값어치와 무게가 있다.
무게 때문에 도둑은 고를 수 있는 물건이 한정되어 있다.
그러므로 가방에 다 담을 수 있는 내에서 가장 비싼 물건을 훔치고자 한다.
여기서 세 가지 선택이 있다.
1) 모든 경우를 다 세어본다.
물건의 갯수가 n개라면, 각각의 물건은 ( 가방에 넣는가, 안 넣는가 ) 의 두 가지 경우가 있다.
전부 2^n가지의 경우를 세어보면 된다.
2) 넣을 수 있는 가장 비싼 물건부터 넣는다. (Greedy Algorithm)
그럴듯 하지만 생각한것처럼 최적의 해는 나오지 않는다. 예를 들어
$10 / 13 kg
$6 / 6 kg
$5 / 6 kg
가방 15 kg
이라면 6$,5$짜리를 택하는 편이 낫다.
3) 동적 계획법(dynamic programming)을 사용합니다.
dyn[i][j] = (가방의 크기가 i일때, j번째 물건까지 담을 수 있는 경우 최대 가치)라고 하면,
dyn[0][i] = dyn[j][0]= 0 를 base case로 놓을 수 있다.
그렇다면 점화식을 구해보자.
i가 weight[j]보다 크거나 같으면 이 가방엔 이 물건이 들어갈 수 있다.
그렇다면 j번째 물건을 넣는다고 가정했을 때,
((i-weight[j]) 크기의 가방에 (j-1) 번째 물건까지 넣을 수 있는 경우 최대 가치)에다가 value[j]를 더하는 모든 경우가 가능하다.
어느 것이 최대인가는 경우에 따라 다르기 때문에 시도해봐야 한다.
이 물건을 안 넣기로 하거나 가방 크기때문에 넣을 수 없다면,
i번째 가방에 j-1번째 물건을 넣을 수 있는 경우 최대 가치를 그대로 쓸 수 있다.
i≥weight[j]이면 dyn[i][j]=max(dyn[i][j-1],max(dyn[i-weight[j]][j]+value[j]))
i<weight[j]이면 dyn[i][j]=dyn[i][j-1]
이렇게 하면 답은 dyn[가방 크기][마지막 물건].
'알고리즘 문제풀기 > DP' 카테고리의 다른 글
행렬을 이용한 접근 (0) | 2017.01.14 |
---|---|
APIO 2010 1번 특공대(Commando) (0) | 2015.06.30 |
Convex Hull Trick (0) | 2015.01.18 |
Bitonic Tour (1) | 2013.11.24 |
Tiling Problem (0) | 2013.11.24 |