DP를 복습하기 위해 이전에 풀었던 배낭 문제를 다시 풀어봤습니다.
이전에는 1차원 배열을 활용해 풀었더군요. 이번에는 2차원 배열을 이용한 정석(?)적인 풀이입니다.
까지
의 최적값을 고려
해야 합니다.고려
한다는 것과 물건 i를 배낭에 넣는다
는 것은 다른 행위입니다.고려
할 수 있습니다. (전체 배낭의 용량을 K,i번째 물건의 무게가 Wi, 가치가 Vi일 때)for (i는 1부터 n까지)
for( w는 1부터 W까지)
if(wi > W){
board[i][w] = board[i-1][w]
}else{
board[i][w] = max(vi+board[i-1][W-wi], board[i-1][w])
}
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int K = sc.nextInt();
List<Obj> lst = new ArrayList<Obj>();
int[][] board = new int[N + 1][K + 1];
for (int i = 0; i < N; i++) {
int W = sc.nextInt();
int V = sc.nextInt();
lst.add(new Obj(W, V));
}
for (int i = 1; i <= N; i++) { // i번째 물건
for (int j = 1; j <= K; j++) { // 배낭의 무게가 j일때
Obj obj = lst.get(i - 1);
if (obj.W > j) { // j물건을 담을 수 없는 경우
board[i][j] = board[i - 1][j];
} else {
board[i][j] = Math.max(board[i - 1][j], obj.V + board[i - 1][j - obj.W]);
}
}
}
System.out.println(board[N][K]);
}
static class Obj {
int W;
int V;
public Obj(int w, int v) {
super();
W = w;
V = v;
}
@Override
public String toString() {
return "Obj [W=" + W + ", V=" + V + "]";
}
}
}
여분의 무게가 4kg일 때 우리는 2kg짜리 물건 1을 선택하고(A), 남은 2kg을 최적의 가치로 채워야 합니다(B).
A과정에서 물건1을 사용했기 때문에 B과정을 진행할 때 2kg의 최적의 가치는 0이 되어야 합니다.
1차원 배열에서는 이러한 내용이 고려되지 못하고 2kg물건이 여러개인 것처럼 14로 업데이트 됩니다.
뒤에서부터 채울 경우 board[i-w]가 아직 갱신되지 않은 상태이기 때문에 올바르게 가치를 고려할 수 있습니다.