https://www.acmicpc.net/problem/12865


이 문제는 0/1 배낭 문제(0/1 Knapsack Problem)로, 동적 계획법(DP, Dynamic Programming)을 사용해 해결할 수 있습니다. 각 물건에 대해 선택할지 말지를 결정하여 배낭의 최대 가치를 계산하는 문제입니다.
N개의 물건이 있고, 각 물건에는 무게 W와 가치 V가 있습니다.K까지의 배낭에 물건들을 담을 수 있으며, 가치의 합이 최대가 되도록 물건을 고르는 것이 목표입니다.이 문제는 동적 계획법(DP)을 사용하여 해결합니다. DP 테이블을 이용해 최대 가치를 누적 계산하면서 최적의 선택을 찾습니다.
dp[i][w]는 i번째 물건까지 고려했을 때, 배낭의 무게가 w일 때의 최대 가치를 의미합니다.dp[i][w] = max(dp[i-1][w], dp[i-1][w-W] + V)dp[i-1][w]: i번째 물건을 선택하지 않는 경우.dp[i-1][w-W] + V: i번째 물건을 선택하는 경우(이전 배낭 무게에서 현재 물건의 무게 W를 뺀 상태에서의 최대 가치에 현재 물건의 가치를 더한 값).import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] inputs = br.readLine().split(" ");
int N = Integer.parseInt(inputs[0]);
int K = Integer.parseInt(inputs[1]);
int[][] item = new int[N+1][2];
for (int i = 1; i <= N; i++) {
inputs = br.readLine().split(" ");
item[i][0] = Integer.parseInt(inputs[0]); // 무게 W
item[i][1] = Integer.parseInt(inputs[1]); // 가치 V
}
// DP 테이블 선언 (0으로 초기화)
int[][] dp = new int[N+1][K+1];
for (int i = 1; i <= N; i++) {
for (int k = 0; k <= K; k++) {
dp[i][k] = dp[i-1][k]; // i번째 물건을 선택하지 않은 경우
if (k - item[i][0] >= 0) { // i번째 물건을 선택할 수 있는 경우
dp[i][k] = Math.max(dp[i][k], dp[i-1][k-item[i][0]] + item[i][1]);
}
}
}
// 배낭에 담을 수 있는 최대 가치 출력
System.out.println(dp[N][K]);
}
}
N은 물건의 수, K는 배낭이 버틸 수 있는 최대 무게.W[i]는 각 물건의 무게, V[i]는 각 물건의 가치를 나타냅니다.dp[i][j]는 i번째 물건까지 고려했을 때, 배낭의 최대 무게가 j일 때 가질 수 있는 최대 가치를 저장합니다.i번째 물건을 선택할지 여부에 따라 값을 갱신합니다.j가 i번째 물건의 무게보다 크거나 같다면, 그 물건을 선택할 수 있습니다.dp[i][j]는 이전 단계에서 물건을 선택하지 않았을 때의 값(dp[i-1][j])과, 선택했을 때의 값(dp[i-1][j-W[i]] + V[i]) 중 큰 값을 선택합니다.dp[i-1][j]).K일 때의 최대 가치를 출력합니다(dp[N][K]).O(N * K)N은 물건의 수, K는 배낭의 최대 무게.N개의 물건을 하나씩 고려하고, 각 물건에 대해 배낭의 무게 K까지 반복하면서 값을 갱신하므로, 전체 시간 복잡도는 O(N * K)입니다.O(N * K)N개의 물건과 K개의 무게를 기준으로 저장되므로, 공간 복잡도는 O(N * K)입니다.