접근
DP 알고리즘 다시 봐야지! 하면 항상 냅색 문제부터 먼저 풀었더니 결국 감이 없는 상태에서 솔루션 참고하고 내 힘으로 풀었던 적은 없는 것 같다. 그래서 이번에는 쉬운 dp 문제들로 먼저 빌드업을 하고왔다 ㅎ 처음에 dp가 어려웠던 이유는 자꾸 그리디처럼 접근해서 그랬던 것 같다. 그냥 이전의 결과를 활용해서 하나씩 새로운 값을 누적하여 계산하면 된다.
짐을 쌀 때 (1) 물건을 포함하는 경우 (2) 물건을 포함하지 않는 경우 2가지로 나뉘기 때문에, 특정 무게일 때 두 가지 경우 중 더 높은 가치를 가지는 값을 저장하면 된다. 즉 무게는 1부터 k의 최대값(100,000)까지 반복하며, 모든 물건별로 넣고 안넣고를 비교해준다. 이 때 dp[i-1][]을 참조해야 하므로 배열의 크기를 n+1로 잡아줬다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int k = Integer.parseInt(st.nextToken());
int[] weight = new int[n+1];
int[] value = new int[n+1];
int[][] dp = new int[n+1][k+1];
for(int i = 1;i <= n;i++){
st = new StringTokenizer(br.readLine());
weight[i] = Integer.parseInt(st.nextToken());
value[i] = Integer.parseInt(st.nextToken());
}
for(int i = 1;i <= n;i++){
for(int j = 1;j <= k;j++){
if(weight[i] > j) // 해당 물건을 넣을 수 없음
dp[i][j] = dp[i-1][j];
else // 물건을 넣지 않는 경우와 넣는 경우 비교
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i]);
}
}
System.out.println(dp[n][k]);
}
}
'Algorithm' 카테고리의 다른 글
[백준] 20922: 겹치는 건 싫어 JAVA (0) | 2023.01.15 |
---|---|
[백준] 11054: 가장 긴 바이토닉 부분 수열 JAVA (0) | 2023.01.10 |
[백준] 1932: 정수 삼각형 JAVA (0) | 2023.01.09 |
[백준] 1912: 연속합 JAVA (0) | 2023.01.08 |
[백준] 9095: 1, 2, 3 더하기 JAVA (0) | 2023.01.08 |