
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]가 아직 갱신되지 않은 상태이기 때문에 올바르게 가치를 고려할 수 있습니다.