맞는데 왜 틀릴까..?

알고리즘 문제/다이나믹 프로그래밍

[Java] 배낭 문제 (안녕)

안도일 2023. 1. 12. 01:38

진짜 평범한 배낭 문제 중에 한 문제다.

 

이 문제에서 N의 범위가 20으로 비교적 작은 범위로 제한되어 있어 ArrayList를 사용하지 않고 크기가 22인 배열을 사용해 문제를 풀 수 도 있었지만 그냥 가변배열을 사용하고 싶어서 ArrayList를 선택했다.

 

배낭 문제에서 [물품의 수 = 사람의 수] 로, [견딜 수 있는 무게 = 체력] 으로 변환하면 쉽게 풀 수 있다. 

 

2차원 배열 선언하는 게 갑자기 생각이 안 나서 헷갈렸다. 행과 열의 구분을 헷갈리지 않도록 확실하게 기억해야 할 필요가 있을 듯

 

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

 

1535번: 안녕

첫째 줄에 사람의 수 N(≤ 20)이 들어온다. 둘째 줄에는 각각의 사람에게 인사를 할 때, 잃는 체력이 1번 사람부터 순서대로 들어오고, 셋째 줄에는 각각의 사람에게 인사를 할 때, 얻는 기쁨이 1번

www.acmicpc.net

 

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine()); //물품의 수 (사람 수)
        int K = 99; //견딜 수 있는 무게 (체력)
        int[][] dp = new int[N+1][K+1]; //가로가 100 세로가 N+1

        ArrayList<Integer> weight = new ArrayList<>();
        ArrayList<Integer> value = new ArrayList<>();

        StringTokenizer st = new StringTokenizer(br.readLine());
        StringTokenizer st2 = new StringTokenizer(br.readLine());

        weight.add(0); //dp 문제이기 때문에 인덱스 0을 0으로 초기화
        value.add(0);
        for (int i = 0; i < N; i++) {
            weight.add(Integer.parseInt(st.nextToken()));
            value.add(Integer.parseInt(st2.nextToken()));
        }
        
        for(int i=1; i<N+1; i++){
            for(int j=1; j<K+1; j++){
                if(j<weight.get(i)){
                    dp[i][j] = dp[i-1][j];
                }
                else{
                    dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weight.get(i)]+value.get(i));
                }
            }
        }
        System.out.print(dp[N][K]);
    }
}

 

 

배낭 문제 핵심 

  •  j < weight : d[i][j] = d[i-1][j]
  • else: d[i][j] = max( dp[i-1][j], d[i-1][ j-weight[i] ]+value[i] ) 

 

배낭 문제에 대해 기억이 나지 않는다면 아래 글을 다시 보자.

 

https://com-squadleader.tistory.com/47

 

배낭 (평범한 배낭 문제)

d[N][K]는 N번째 물건 까지 살펴보았을 때, 무게가 K인 배낭의 최대 가치 이다. 물건을 배낭에 담을 때, 1. 현재 배낭의 허용 무게보다 넣을 물건의 무게가 더 크다면 넣지 않는다. 2. 그렇지 않다면,

com-squadleader.tistory.com

https://com-squadleader.tistory.com/46

 

배낭 문제 (Knapsack Problem)

배낭 문제(Knapsack Problem) 배낭 문제란 배낭에 담을 수 있는 무게의 최대값이 정해져 있고, 일정한 가치와 무게가 정해져있는 짐들을 배낭에 담을 때, 가치의 합이 최대가 되도록 짐을 고르는 방법

com-squadleader.tistory.com