[01 배낭 이론] 01 배낭 문제 dp[j] (롤링 배열) <동적 프로그래밍 보드>

[01 백팩 이론] 01 백팩 문제 dp[j]

n개의 아이템과 최대 w의 무게를 지닐 수 있는 배낭이 있습니다.
i번째 항목의 가중치는 가중치[i]이고, 얻은 값은 값[i]이다.
각 품목별로 품목이 1개뿐이므로 배낭에 어떤 품목을 넣어야 하는지 알아보고 품목의 총 가치가 가장 큽니다.

답변

동적 프로그래밍

  • dp 배열과 아래 첨자의 의미를 결정합니다
    . 롤링 배열 dp[j]: j용량이 의 배낭은 최대 값이 의 항목을 운반할 수 있습니다.dp[j]

  • 의 용량을 가진 배낭이 운반할 수 있는 최대값이
    dp[j]되는 재귀 공식을 결정합니다 . 의 용량을 가진 배낭이 운반할 수 있는 최대값을 나타내는 것으로 추론 할 수 있습니다 . 용량에 아이템 가치를 더한 배낭을 나타냅니다 . (즉, 아이템을 넣은 후 용량이 의 배낭 의 가치는 다음과 같습니다. ) 두 가지 옵션이 있습니다:j
    dp[j]dp[j - weight[i]]dp[j - weight[i]]j - weight[i]dp[j - weight[i]] + value[i]j - 物品i重量ijidp[j]
    dp[j]

    • 하나는 자체를 취하는 것인데, dp[j]이는 2차원 dp 배열과 동일합니다 dp[i-1][j]. 즉, 항목이 배치되지 않습니다 i(지난번과 동일).
    • 하나는 가져가는 것 dp[j - weight[i]] + value[i], 즉 물건을 넣어서 i최대값을 지정하는 것이고, 결국 최대값을 추구하는 것이다.
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
  • dp 배열을 초기화하는 방법

dp[j]의미 : j용량이 의 배낭의 경우 소지품의 값은 최대 입니다. dp[j]먼저, dp[0]=0.
dp 배열을 도출할 때 가장 큰 값을 갖는 숫자를 취해야 합니다. 값이 질문에 주어진 값이 모두 양의 정수이면 첨자는 0이 아닙니다. 그냥 모두 0으로 초기화하면 됩니다. 즉, 다른 첨자의 값은 모두 0으로 초기화되므로 dp 배열이 최대값을 취할 수 있습니다. 초기 값으로 덮어쓰이는 대신 재귀 수식 프로세스 중에.

  • 순회 순서를 결정합니다.
    2차원 dp를 순회할 때 배낭 용량은 작은 것부터 큰 것입니다. 1차원 dp를 순회할 때 배낭 용량은 큰 것에서 작은 것입니다. 항목을 먼저
    정방향으로 배치한 다음 역순으로 배낭에 담습니다. 역순 순회는 항목이 i한 번만 삽입되도록 하기 위한 것이며, 양순으로 순회하면 항목 0이 여러 번 추가됩니다.
for(int i = 0; i < weight.size(); i++) {
    
     // 遍历物品
    for(int j = bagWeight; j >= weight[i]; j--) {
    
     // 遍历背包容量
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

    }
}
  • dp 배열을 추론하는 예를 들어보겠습니다(dp 배열 인쇄).
    배낭의 최대 무게는 4입니다. 물건:
무게
항목 0 1 15
항목 1 20
항목 2 4 30

여기에 이미지 설명을 삽입하세요.

public class Solution {
    
    
    public static void main(String[] args) {
    
    
        int[] weight = {
    
    1, 3, 4};
        int[] value = {
    
    15, 20, 30};
        int bagWight = 4;
        testWeightBagProblem(weight, value, bagWight);
    }

    public static void testWeightBagProblem(int[] weight, int[] value, int bagWeight){
    
    
        int wLen = weight.length;
        //定义dp数组:dp[j]表示背包容量为 j 时,能获得的最大价值
        int[] dp = new int[bagWeight + 1];
        
        //遍历顺序:先遍历物品,再遍历背包容量(倒序)
        for (int i = 0; i < wLen; i++){
    
    
            for (int j = bagWeight; j >= weight[i]; j--){
    
    
                dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
            }
        }
        
        //打印dp数组
        for (int j = 0; j <= bagWeight; j++){
    
    
            System.out.print(dp[j] + " ");
        }
    }
}

추천

출처blog.csdn.net/qq_44033208/article/details/132640280