【动态规划】01完全背包理论

完全背包理论基础的一些理解

指路地址:动态规划:完全背包理论基础

二维实现

  • 初始化dp[0][j]时,可以重复取

    dp[0][j] = (j / weight[0]) * value[0];

  • 对于状态转移与0-1背包的区别

    //01背包
    dp[i][j] = Math.max(dp[i-1][j], value[i]+dp[i-1][j-w[i]]);
    //完全背包
    dp[i][j] = Math.max(dp[i-1][j], value[i]+dp[i][j-w[i]]);
    其区别在于每个物品是否可重复选。
    所以dp[i-1][j-w[i]]表示选了当前第i个物品后只能从前i-1个物品中进行选择,并且扣除了当前第i个物品的weight;
    而dp[i][j-w[i]]表示尽管我选了当前物品,也把当前物品的weight从背包容量中扣除了,但是我任然可以在这i个物品中继续选择。

import java.util.Scanner;

public class Main {
    public static void  main(String[] args){
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int bagWeight = scanner.nextInt();
        int[][] dp = new int[n][bagWeight +1];
        int[] weight = new int[n];
        int[] value = new int[n];
        for (int i = 0; i<n; i++){
            weight[i] = scanner.nextInt();
            value[i] = scanner.nextInt();
        }
        // 初始化时,可以重复取
        for(int j = 0; j <= bagWeight; j++){
            if (weight[0] <= j) {
                dp[0][j] = (j / weight[0]) * value[0];
            } 
        }

        for (int i = 1; i< n; i++){
            for (int j = 0; j <= bagWeight; j++){
                if(j >= weight[i]) {
                    // dp[i][j-weight[i]] + value[i]
                    // i的意思是可以任取0-i
                    dp[i][j] = Math.max(dp[i-1][j], dp[i][j-weight[i]] + value[i]);
                } else {
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
        System.out.println(dp[n-1][bagWeight]);
    }
}

一维实现

  • 与0-1背包的一维实现,不同之处在于内层遍历顺序为从前往后,从前往后,即,更新过后的背包,依然可以被后面用到,就是说,可以重复取。
posted @ 2024-11-20 15:18  chendsome  阅读(37)  评论(0)    收藏  举报