(Python, Java) 백준 12865번 평범한 배낭 - class 4
[문제 링크]
Python 풀이
접근 방법
처음에는 백트래킹으로 풀었는데 시간초과가 발생했다. 그래서 인터넷으로 검색해보니 냅색 알고리즘 을 사용해야 했는데 이 알고리즘을 처음 보는 것이라 혼자 풀지 못했다. 공부하고 보니 그냥 다이나믹프로그래밍 문제로 점화식만 잘 세우면 되는 문제였다. dp의 쉬운 문제들은 대부분 점화식이 바로 앞에 것만 사용하는 것인데 이렇게 조금 어려워 지면 2차원 배열로 점화식이 세워진다.
해결
- 무게별 최대 가치를 저장할 2차원 dp테이블을 만든다.
- 첫 줄은 0으로 1부터 k까지 배낭을 채운다.
- 모든 물건에 대해 허용 무게가 1부터 K까지 배낭에 넣어보면서 dp 테이블을 수정한다.
- 현재 물건의 무게가 배낭의 허용무게보다 큰 경우, 전에 물건의 결과값을 가져온다.
- 현재 물건의 무게가 배낭의 허용무게보다 작은 경우, max(현재 물건의 가치 + 이전 물건의 (허용무게-현재물건무게)의 최대 가치, 이전 물건의 허용무게 최대 가치)
import sys
input = sys.stdin.readline
# 물건 개수, 버틸 수 있는 무게
n, k = map(int, input().split())
dp = [[0] * (k + 1) for _ in range(n + 1)] # 무게별 최대 가치 저장소
# 모든 물건에 대해서 확인
for i in range(1, n + 1):
# 무게, 가치
w, v = map(int, input().split())
# 무게별 확인
for j in range(1, k + 1):
# 현재 물건의 무게가 가방 무게 j보다 무거운 경우
if w > j:
dp[i][j] = dp[i - 1][j] # 전에 물건 결과값 가져오기
else:
dp[i][j] = max(v + dp[i - 1][j - w], dp[i - 1][j])
print(dp[n][k])
Java 풀이
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int k = scanner.nextInt();
int[][] dp = new int[n + 1][k + 1];
for (int i = 1; i <= n; i++) {
int w = scanner.nextInt();
int v = scanner.nextInt();
for (int j = 1; j <= k; j++) {
if (j >= w) {
dp[i][j] = Math.max(v + dp[i - 1][j - w], dp[i - 1][j]);
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
System.out.println(dp[n][k]);
scanner.close();
}
}