일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 10분
- 스탭퍼
- 파비최
- 괜찮음
- Daily Challenge
- 뭐든
- 영어공부
- leetcode
- 월간
- 링피트
- realclass
- FIT XR
- 개발자
- Problem Solving
- 만화도
- 30분
- 사이드
- 영어원서읽기
- 매일
- English
- 리얼 클래스
- 미드시청
- 쓰릴오브파이트
- Writing
- 3줄정리
- 화상영어
- 운동
- 읽기
- 프로젝트
- 잡생각
Archives
- Today
- Total
파비의 매일매일 공부기록
5.9 0-1 배낭 - 재귀 본문
그 이름도 유명한 배낭 문제. (https://www.acmicpc.net/problem/12865)
간단히 문제를 설명하자면
무게, 가격을 나타내는 몇개의 쌍이 존재할 때
무게의 한도치가 정해진다면 최대값을 구하는 문제다.
일단 재귀를 사용해서 풀려면 아래의 두가지 경우의 반복이라고 볼 수 있다.
물건이 n개 있다고 할 때, n번 물건을 선택한다면
1. 물건을 배낭에 넣을 때 : 남은 물건의 갯수는 n-1, 배낭에 추가로 넣을 수 있는 최대 무게는 C - weight[n-1]이 됨. 물건의 가치는 value[n-1]만큼 증가. 결국 n-1개의 물건과 C - weight[n-1]의 배낭이 있는 문제로 원래 문제와 동일한 형태가 된다.
2. 물건을 배낭에 넣지 않을 때 : 물건은 n-1개, 배낭에 추가가 가능한 최대 무게는 C. 결국 n-1개의 물건과 C의 무게를 넣을 수 있는 배낭 문제와 동일.
종료조건 : 남은 물건이 없거나 배낭이 꽉 찼을 때
위의 내용을 코드로 옮기면 다음과 같다.
import sys
sys.setrecursionlimit(10**5)
def solve(c, weight, value, n):
if n <= 0 or c <= 0:
return 0
if weight[n-1] > c:
return solve(c, weight, value, n-1)
carry = value[n-1] + solve(c - weight[n-1], weight, value, n-1)
leave = solve(c, weight, value, n-1)
return max(carry, leave)
if __name__ == '__main__':
n, c = map(int, input().split())
weight = []
value = []
for _ in range(n):
a, b = map(int, input().split())
weight.append(a)
value.append(b)
print(solve(c, weight, value, n))
각 노드가 두개의 자식 노드를 가지고 있는 재귀 호출 구조를 갖고 있다.
결국 같은 하위 문제를 반복 계산하는 경우가 존재하므로 DP로 풀 수 있다.
반응형
'Study > Algorithm 문제풀이' 카테고리의 다른 글
5.10 최장 회문 부분 수열의 길이 - 재귀 (0) | 2021.09.23 |
---|---|
5.9 0-1 배낭 - DP (0) | 2021.09.22 |
5.8 철근 자르기 - DP (0) | 2021.09.20 |
5.8 철근 자르기 - 메모전략 (0) | 2021.09.19 |
5.8 철근 자르기 - 재귀 (0) | 2021.09.18 |
Comments