인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

욕망의햄버거님의 프로필 이미지

작성한 질문수

2주만에 통과하는 알고리즘 코딩테스트 (2024년)

활용 ( 바텀업 DP )

[활용(바텀업DP)] 추가질문 10:34

작성

·

358

·

수정됨

1

안녕하십니까 코딩센세님!

잘 와닿지 않는 부분이 있어서 3일 정도 곱씹어보다가, 제가 생각한 바가 맞는지 검토가 필요해서 추가로 질문을 작성해봅니다.

 

=====================================

[활용 (바텀업DP)] 강의에서 10:34초 쯤에,
냅색 문제의 탑다운DP 코드 일부분을 가리키며 이렇게 말씀하십니다. "이 재귀함수는 뒤에서부터 채워주는 형태죠?"

Q1. 여기서, 뒤에서 채워준다는게 dp의 값을 idx==N부터 0을 리턴하며 dp[idx]에 값이 채워지기 때문이라고 이해하면 맞을까요?

Q1-1. 위의 질문을 다르게도 표현하자면, 탑다운DP 방식으로 접근했기 때문에 엣지에서 시작하므로 끝에서부터 채워진다고 볼 수 있기 때문일가요?

Q1-3. Q1.에서 이해한 바가 맞다면, 그와 같은 논리를 바탕으로, [활용 (바텀업 DP)] 강의 10:26초에서 설명하신 다음 코드에서 idx 부분을 빼줘야 하는 이유를 이해했지만,

weight에서 item만큼의 무게를 빼줘야 하는 이유가 아직까지 이해가 되 지 않습니다..

dp[idx][weight] = max(dp[idx - 1][weight - items[idx][0]] + items[idx][1], dp[idx-1][weight]

=====================================

 

[활용 (바텀업DP)] 강의에서 07:22~07:39초인덱스를 초과한 경우에 대한 연산을 설명하시는데요.

Q2. if idx + interview[idx][0] > N:
dp[idx] = dp[idx+1]
위 코드를 가리키시며, "인덱스가 넘는 경우는 그냥 뒤에걸, 선택 안하는거를 추가해준다고 하고.." 라고 설명하셨습니다. 저는 이게 어떤 부분을 의도하시는건지 와닿지가 않았습니다.

바텀업 dp는 코드를 따라가며 종이에 dp테이블을 적어보려 노력해봐도, 이해를 다 못해서 그런지 그려지지가 않더라구요.

dp테이블 그리면서 생각을 추적하는 방법을 곁들여서 설명을 또 한번 부탁드려도 될지요?

Q2-1. dp 인덱싱 부분을 제 입맛대로 조금 조작을 해봤는데요. 무슨 이유 때문에 아래의 코드는 90%에서 오류가 나는지 분석이 어렵습니다. 제가 첨부한 코드를 예시로 사용해서 설명을 Q2.에 대한 설명을 비교해주시면 감사드리겠습니다!

# 바텀업DP 풀이

# 물건의 수, 배낭의 무게
# 4, 7
N, B = map(int, input().split())

# col_idx: 0, 1
# row_idx: 0, 1~3
# [idx][0]: Weight, [idx][1]: Value
items = [list(map(int, input().split())) for _ in range(N)]

# bag_wigth(col_idx): 0, 1~7
# item_idx(row_idx): 0, 1~3
dp = [[0 for _ in range(B+1)] for _ in range(N)]


# idx: 0~3
# bag_weight: 0~7
for idx in range(N):
    item_weight = items[idx][0]
    item_value = items[idx][1]
    for bag_weight in range(B+1):
        if item_weight > bag_weight:
            dp[idx][bag_weight] = dp[idx-1][bag_weight]
        else:
            dp[idx][bag_weight] = max(
                dp[idx-1][bag_weight - item_weight] + item_value,
                dp[idx-1][bag_weight])

print(items)
print(dp)
print(dp[N-1][B])

 

늘 친절한 답변에 감사드리며..!

저도 더욱 발전해서 코딩센세처럼 지식을 나누는 기쁨을 누릴수있도록 노력하겠습니다!

 p.s. 사실 솔직히 말씀드리면 print(dp[N-1][B]) 에서 N-1을 해야 하는 이유도 완벽하게 이해하지 못햇슴당 ㅎㅎ..

답변 1

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다. 욕망의햄버거님, 알고리즘 문제 해결에 대한 깊이 있는 질문 주셔서 감사합니다. 먼저, 동적 프로그래밍(Dynamic Programming, DP)의 접근 방식에 대한 귀하의 이해가 올바른지 검증하고, 몇 가지 질문에 대해 답변 드리겠습니다.

Q1. 맞습니다. 탑다운 접근 방식에서는 재귀 함수를 사용해 문제를 작은 하위 문제로 나누는 과정에서 idx==N 부터 시작하여 이후에 dp[idx]에 값을 채우게 됩니다.

Q1-1. 네, 탑다운 DP는 상위의 문제부터 해결하고 결과를 저장해가며 하위의 문제로 내려가는 구조이기 때문에 ‘엣지에서 시작하는ㅡ 끝에서부터 채워진다’고 표현할 수 있습니다.

Q1-3. 바텀업 접근 방식에서 weight에서 item의 무게만큼 빼주는 이유는 해당 아이템을 배낭에 포함했을 때, 그 이전 단계에서 어떠한 아이템들을 배낭에 넣었는지를 고려하기 위함입니다. 이는 아이템을 추가해서 배낭의 무게가 weight가 되도록 만들 때, 배낭에서 그 아이템의 무게를 고려해야하기 때문입니다.

Q2. 이 코드는 인터뷰가 idx 날짜에 있고, 인터뷰가 idx+interview[idx][0] 날짜를 초과할 때 현재 idx에서 얻을 수 있는 최댓값은 다음 idx일 때의 최댓값과 같다는 것을 의미합니다. 즉, idx 날짜에 인터뷰를 할 수 없기 때문에 생략하고, 다음 날짜에 가능한 값을 가져오는 것이죠.

Q2-1. 코드에 오류가 발생하는 정확한 원인을 파악하기 위해서는 오류 메시지나 실행 환경을 더 자세히 알아야 하겠지만, dp 인덱싱 과정 중에 idx가 0부터 시작하기 때문에 dp[idx-1][...] 형태로 전 단계를 참조할 때 잘못된 인덱싱으로 오류가 발생할 수 있습니다.

마지막으로, print(dp[N-1][B]) 에서 N-1을 하는 이유는 Python의 인덱싱이 0부터 시작하기 때문입니다. 따라서, N개의 아이템을 가지고 DP 테이블을 채웠을 때 마지막 아이템의 인덱스는 N-1이 되므로, 그에 해당하는 값을 출력하며 최종 결과를 확인하는 것입니다.

코딩 테스트와 알고리즘 학습에 대한 열정이 느껴지며, 코딩센세처럼 지식을 나눌 수 있는 나날들이 곧 오실 것이라 생각합니다. 도움이 되었기를 바라며, 추가적인 질문이 있으시면 언제든지 문의 주세요!