【算法练习】leetcode算法题合集之动态规划背包问题篇

背包概念

01背包问题

有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weights[i],得到的价值是value[i]。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

输入:weight [1,3,4] value:[15,20,30],最多能背重量总和为4的物品。

dp[i][j]指的是在[0,i]个物品中在容量为j的背包中可选择的最大价值。

如果当前容量是小于weight[i],那么表示放不下第i个物品,所以dp[i][j] = dp[i - 1][j];

如果当前容量是大于weight[i],那么表示可以放下第i个物品,所以当前最大价值等于放这个物品的最大价值dp[i - 1][j - weight[i]] + value[i]和不放这个物品dp[i - 1][j]的最大价值。

public class Pack1 {
   
   

    public static void main(String[] args) {
   
   

        int[] weight = {
   
   1, 3, 4};
        int[] value = {
   
   15, 20, 30};
        int bagSize = 4;
        System.out.println(testWeightBagProblem(weight, value, bagSize));

    }

    private static int testWeightBagProblem(int[] weight, int[] value, int bagSize) {
   
   
        int size = weight.length;
        int[][] dp = new int[size][bagSize + 1];

        for (int i = weight[0]; i <= bagSize; i++) {
   
   
            dp[0][i] = value[0];
        }
        for (int i = 1; i < size; i++) {
   
   
            for (int j = 1; j <= bagSize; j++) {
   
   
                if (j < weight[i]) {
   
   
                    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]);
                }
            }
        }
        return dp[size - 1][bagSize];
    }
}

一维思路

为啥不能int j = weight[i]; j <= bagSize; j++,是因为想要的是上一轮的数据。当i-1变成i的时候,计算dp[j]的时候,希望dp[j - weight[i]]是在当前轮次没有计算过的,是dp[i-1][j-weight[i]]。如果j从小到大计算,当计算到最大值的时候,dp[j-weight[i]]已经计算过了,更新成了dp[i][j-weight[i]]

    private static int testWeightBagProblem2(int[] weight, int[] value, int bagSize) {
   
   
        int size = weight.length;
        int[] dp = new int[bagSize + 1];
        for (int i = 0; i < size; i++) {
   
   
            for (int j = bagSize; j >= weight[i]; j--) {
   
   
//            for (int j = weight[i]; j <= bagSize; j++) {
   
   
                dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
            }
        }
        return dp[bagSize];
    }

完全背包

完全背包是物品有无数个,可以选几个也可以不选。

如何去理解,01背包从后往前,完全背包从前往后遍历。从后往前获取的永远是dp[i-1][j]的数据,是没有第i个物品的情况下的计算结果。所以dp[j]的计算结果总是物品只能选择单个。

public class Pack2 {
   
   

    public static void main(String[] args) 

相关推荐

  1. 算法练习leetcode算法动态规划

    2024-02-07 04:40:01       63 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-07 04:40:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-07 04:40:01       101 阅读
  3. 在Django里面运行非项目文件

    2024-02-07 04:40:01       82 阅读
  4. Python语言-面向对象

    2024-02-07 04:40:01       91 阅读

热门阅读

  1. Vue3 中的各种ref

    2024-02-07 04:40:01       49 阅读
  2. 网络版本计算器

    2024-02-07 04:40:01       40 阅读
  3. 网络安全面试题收集

    2024-02-07 04:40:01       58 阅读
  4. UI自动化中元素无法定位问题解决方法

    2024-02-07 04:40:01       57 阅读
  5. 【从零开始学设计模式】第一章_设计模式简介

    2024-02-07 04:40:01       58 阅读
  6. 【数论】矩阵快速幂

    2024-02-07 04:40:01       50 阅读
  7. 深度学习预备知识2——数据预处理

    2024-02-07 04:40:01       53 阅读
  8. C语言:斐波那契数列中的合数

    2024-02-07 04:40:01       56 阅读
  9. 学习使用shell脚本获取进程号并杀死进程

    2024-02-07 04:40:01       45 阅读
  10. iOS面试题

    2024-02-07 04:40:01       50 阅读
  11. nodejs生成有样式的excel

    2024-02-07 04:40:01       48 阅读
  12. 一台服务器可以支持多少TCP连接

    2024-02-07 04:40:01       44 阅读
  13. SOLID原理:用Golang的例子来解释

    2024-02-07 04:40:01       57 阅读
  14. 【go】gorm\xorm\ent多表联查

    2024-02-07 04:40:01       55 阅读
  15. 代码随想录算法训练营第二十四天| 77. 组合

    2024-02-07 04:40:01       52 阅读