[백준] 12865번 평범한 배낭 - Java/자바
문제
입력
첫 줄에 물품의 수 N(1 ≤ N ≤ 100)과 준서가 버틸 수 있는 무게 K(1 ≤ K ≤ 100,000)가 주어진다. 두 번째 줄부터 N개의 줄에 거쳐 각 물건의 무게 W(1 ≤ W ≤ 100,000)와 해당 물건의 가치 V(0 ≤ V ≤ 1,000)가 주어진다.
입력으로 주어지는 모든 수는 정수이다.
출력
한 줄에 배낭에 넣을 수 있는 물건들의 가치합의 최댓값을 출력한다.
접근방법
동적계획법을 이용한 Knapsack 알고리즘을 이용해서 최대 가치를 구하는 문제다. 이 알고리즘은 현재 물건을 포함할 경우와 포함하지 않을 경우로 나눠서 생각한다. 즉, i번째 물건을 포함할 경우 d[i][j-w[i]] + v[i]
이 되고, 포함하지 않을 경우 d[i-1][j]
이 된다. 두 가지 중에서 최댓값을 저장해주면 된다. 이 때 d[i][j]
는 현재 i
번째 물건까지 고려해서 가방 용량이 j
일 때의 최대 가치를 나타낸다.
이 과정을 N
개의 물건에 대해 반복하면 마지막 물건까지 고려했을 때 가방 용량 K
안에서 얻을 수 있는 최대 가치를 구할 수 있다.
그림으로 이해해보면 다음과 같다.
i, j | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
1(6, 13) |
0 | 0 | 0 | 0 | 0 | 13 | 13 |
2(4, 8) |
0 | 0 | 0 | 8 | 8 | 13 | 13 |
3(3, 6) |
0 | 0 | 6 | 8 | 8 | 13 | 14 |
4(5, 12) |
0 | 0 | 6 | 8 | 12 | 13 | 14 |
풀이
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
int[][] d = new int[N+1][K+1];
int[] w = new int[N+1];
int[] v = new int[N+1];
for(int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
w[i] = Integer.parseInt(st.nextToken());
v[i] = Integer.parseInt(st.nextToken());
}
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= K; j++) {
d[i][j] = d[i-1][j];
if(j >= w[i]) {
d[i][j] = Math.max(d[i][j], d[i - 1][j - w[i]] + v[i]);
}
}
}
bw.write(String.valueOf(d[N][K]));
bw.flush();
bw.close();
br.close();
}
}
댓글남기기