Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 리스트
- 파이썬
- BOJ 2606
- LCS2
- 백준 2606
- boj 11053
- 백준 12015
- 가장 긴 증가하는 부분수열
- 12865
- 8-queen
- 타겟 넘버
- 평범한 배낭
- python
- 2606
- list
- 소수찾기
- 백준 9252
- 데카르트 곱
- BFS
- 대소비교
- 백준_2178
- 증가하는 부분수열 2
- 냅색
- 백준 1535
- 프로그래머스
- 9663
- dfs
- 백준
- 알고리즘
- 미로탐색
Archives
- Today
- Total
Devlog_by_0giru
[boj] 안녕_1535 본문
1535번: 안녕
첫째 줄에 사람의 수 N(<=20)이 들어온다. 둘째 줄에는 각각의 사람에게 인사를 할 때, 잃는 체력이 1번 사람부터 순서대로 들어오고, 셋째 줄에는 각각의 사람에게 인사를 할 때, 얻는 기쁨이 1번
www.acmicpc.net
최대 이득을 얻기 위해 주어진 보기들을 적절하게 골라내야 하는 문제다.
문제를 보자마자 DP의 향기가 진하게 뿜어져 나왔지만 사실 어떻게 접근해야 하는지는 잘 몰랐다.
그래서 백트래킹을 이용한 재귀함수 호출로 문제를 해결하려고 시도했더니 엥? 풀렸다...
나중에 알고보니 이 문제는 '냅색(knapsack)' 문제로, 다이나믹 프로그래밍의 아주 대표적인 유형이라더라. 그래서 DP로 다시풀었다.
이 문제를 풀기 전에 '평범한 배낭_12865' 문제로 유형을 익히니 사실상 코드에서 변수명만 바꿔주는 수준으로 풀리더라는...
문제를 푸는 자세한 방법은 위 포스팅에 있다.
이 문제가 하나 다른점이 있다면, 평범한 배낭 문제는 시간제한 때문에 백트래킹을 이용한 재귀는 사용할 수 없다는 점이었다.
+) 문제에서 총 체력이 100이고 체력이 0이하로 떨어지면 안된다는 조건이 있었는데, 나는 냅색 문제로 더 가까이 접근해 풀기 위해서 0부터 체력을 시작해 사람을 만날수록 체력이 쌓여 99가 최대인 조건으로 바꾸어 풀었다. 마치 체력 99가 냅색의 최대 용량인 것처럼 말이다.
- 재귀함수 + 백트래킹을 이용한 코드 (체력을 쌓아가는 식이 아닌 깎아주는 식으로 풀었다.)
"""
백트래킹 재귀를 이용한 풀이
"""
n = int(input())
costs = list(map(int, input().split()))
joys = list(map(int, input().split()))
life = 100
result = 0
# 현재 인덱스, 현재 기쁨, 현재 라이프를 인자로 연산하는 재귀함수
def Recursion(idx, cur_joy, cur_life):
global result
# 종료조건 : 라이프가 0이하일 때
if cur_life <= 0:
# 이전의 기쁨을 결과로 리턴
prev_joy = cur_joy-joys[idx-1]
if prev_joy > result:
result = prev_joy
return
# 종료조건 : 모든 사람을 탐색했을 경우
if idx == n:
if cur_joy > result:
result = cur_joy
return
# 현재 사람을 선택할 경우
Recursion(idx+1, cur_joy+joys[idx], cur_life-costs[idx])
# 현재 사람을 선택하지 않을 경우
Recursion(idx+1, cur_joy, cur_life)
Recursion(0, 0, life)
print(result)
- 2차원 다이나믹 프로그래밍을 이용한 풀이 (체력을 깎아가는 방식이 아닌 0에서 채우는 방식으로 풀었다.)
"""
2차원 DP를 이용한 풀이
"""
n = int(input())
costs = [0]
joys = [0]
cost = list(map(int, input().split()))
joy = list(map(int, input().split()))
costs += cost
joys += joy
costs_limit = 99
dp = [[0] * 100 for _ in range(n+1)]
for i in range(1, n+1):
for j in range(100):
if costs[i] > j:
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i-1][j-costs[i]] + joys[i], dp[i-1][j])
print(dp[n][costs_limit])
'[PS]' 카테고리의 다른 글
[boj] 촌수계산_2644 (0) | 2021.04.02 |
---|---|
[boj] 평범한 배낭_12865 (0) | 2021.03.29 |
[boj] 가장 긴 증가하는 부분 수열2_12015 (0) | 2021.03.08 |
[boj] 미로 탐색_2178 (0) | 2021.03.07 |
[boj] LCS2_9252 (0) | 2021.03.04 |