首页 > 其他分享 >代码随想录Day35 | 01背包问题 二维,01背包问题 一维,416.分割等和子集

代码随想录Day35 | 01背包问题 二维,01背包问题 一维,416.分割等和子集

时间:2025-01-14 12:02:31浏览次数:3  
标签:01 scanner weight int 随想录 value 背包 dp

代码随想录Day35 | 01背包问题 二维,01背包问题 一维,416.分割等和子集

01背包问题 二维

动态规划经典问题

dp定义

dp[i][j]表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少

状态转移方程

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])

  • dp[i - 1][j]表示不把物品i装入背包
  • dp[i - 1][j - weight[i]] + value[i]表示把物品i装入背包,dp[i - 1][j - weight[i]]是背包去除物品i的重量后,可以得到的最大价值

初始化

  • 第一列,即背包容量为0时,肯定是0,数组初始化已经默认是0
  • 状态转移方程要用到i - 1行,所以第一行必须初始化

遍历

先遍历行,也就是先遍历物品,再遍历背包容量

import java.util.Scanner;

public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        // n种物品,背包容量bagWeight
        int n = scanner.nextInt();
        int bagWeight = scanner.nextInt();
        
        int[] weight = new int[n];
        int[] value = new int[n];
        for (int i = 0; i < n; i++)
            weight[i] = scanner.nextInt();
        for (int i = 0; i < n; i++)
            value[i] = scanner.nextInt();
            
        int[][] dp = new int[n][bagWeight + 1];
        
        for (int j = weight[0]; j <= bagWeight; j++) {
            dp[0][j] = value[0];
        }
        
        for (int i = 1; i < n; i++) {
            for (int j = 1; j <= bagWeight; 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]);
            }
        }
        
        System.out.println(dp[n - 1][bagWeight]);
        return;
    }
}

01背包问题 一维

因为在二维里,dp[i][j]的值只与左上角(上一行且左边)的值有关,所以只保存一行的值即可。

状态转移方程

dp[j] = max(dp[j], dp[j - weight[i]] + value[i])

遍历顺序

因为要用到左上角的值,在一维里就是左边的值,所以j要从后往前遍历,不然会影响到左边的值

import java.util.Scanner;

public class Main {
    public static void main (String[] args) {
        Scanner scanner = new Scanner(System.in);
        // n种物品,背包容量bagWeight
        int n = scanner.nextInt();
        int bagWeight = scanner.nextInt();
        
        int[] weight = new int[n];
        int[] value = new int[n];
        for (int i = 0; i < n; i++)
            weight[i] = scanner.nextInt();
        for (int i = 0; i < n; i++)
            value[i] = scanner.nextInt();
            
        int[] dp = new int[bagWeight + 1];
        
        for (int j = weight[0]; j <= bagWeight; j++) {
            dp[j] = value[0];
        }
        
        for (int i = 1; i < n; i++) {
            for (int j = bagWeight; j >= weight[i]; j--) {
                dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
            }
        }
        
        System.out.println(dp[bagWeight]);
        return;
    }
}

416.分割等和子集

难点在于将问题转换为动态规划问题:

  • 视为背包问题,能否把容量为 sum/2 的背包刚好装满
  • 物品的重量与价值相等

然后就是背包问题的代码形式

class Solution {
    public boolean canPartition(int[] nums) {
        if (nums.length < 2) return false;
        // 视为背包问题,能否把容量为 sum/2 的背包刚好装满
        // 物品的重量与价值相等
        int sum = Arrays.stream(nums).sum();
        if (sum % 2 == 1) return false;
        
        int target = sum / 2;
        int[] dp = new int[target + 1];

        for (int i = 0; i < nums.length; i++) {
            for (int j = target; j >= nums[i]; j--) {
                // 取当前数 或 不取当前数
                dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
            }
            // 每次判断是否装满
            if (dp[target] == target)
                return true;
        }

        return dp[target] == target;
    }
}

[j]:

标签:01,scanner,weight,int,随想录,value,背包,dp
From: https://blog.csdn.net/weixin_43992121/article/details/145135730

相关文章

  • web.config站内301永久重定向代码示例
    注:此代码只适用于IIS服务器,如需要将123.asp重定向到123.html,请使用以下代码。修改说明: 在web.config文件中添加301重定向规则,将123.asp重定向到123.html。<?xmlversion="1.0"encoding="UTF-8"?><configuration><system.webServer><rewrite>......
  • 欧拉OpenEuler基于Kubeasz部署k8s.250114
    欧拉OpenEuler基于Kubeasz部署k8s系统优化修改主机名hostnamectlset-hostnamePRD-MS-K8S01vim/etc/hosts172.62.17.101PRD-MS-K8S01172.62.17.102PRD-MS-K8S02172.62.17.103PRD-MS-K8S03关闭防火墙systemctlstopfirewalldsystemctldisablefirewalld关闭se......
  • 计算机毕业设计—311017 spring boot酒店预定系统(源码免费领)
    摘 要信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对酒店客房预定等问题,对酒店信息管理进行研究分析,然后开发设计出酒店预订系统以解决问题。......
  • 代码随想录算法训练营总结
            为期2个月的训练营时间,总算是一步一步的顺利结束了,撒花撒花!!!    这个训练营算是我第一次比较系统的进行学习数据结构和算法以及刷力扣,以前总是刷到一半就半途而费了,这次总算是坚持着跟着群里的打卡节奏一步一步的完结了。    对于内容来说,内......
  • 代码随想录算法训练营第五十九天|KM47.参加科学大会|KM94.城市间货物运输Ⅰ
    47.参加科学大会(第六期模拟笔试)2、堆优化版(该方法没看懂)邻接矩阵的优点:表达方式简单,易于理解检查任意两个顶点间是否存在边的操作非常快适合稠密图,在边数接近顶点数平方的图中,邻接矩阵是一种空间效率较高的表示方法。缺点:遇到稀疏图,会导致申请过大的二维数组造成空间浪费......
  • JavaScript基础01
    一、基本情况#1、介绍JavaScript是一门解释性的脚本语言,主要用来给HTML网页增加动态功能。通常的js是运行在浏览器环境下的,可以帮助我们去控制页面,实现丰富的功能。会有dom和bom的api去操作html文档和浏览器的一些功能。nodejs是运行在计算机环境下的。语法一样,但是因为环......
  • 2025 Homebrew 配置 brew install 国内镜像源指南,快速安装加速(01月13日更新)
    2025Homebrew配置brewinstall国内镜像源指南,快速安装加速(01月13日更新)大家好!......
  • xb21cn Office 2016 绿色版 2025更新版
    软件简介office精简版xb21cn最新版是一款微软Office办公软件的免激活office绿色精简版,xb21cn精简office绿色版提供office2010精简版和Office2016精简版,功能保留三大常用组件Word,Excel,PowerPoint,适合日常使用。版本特点MicrosoftOffice2016/2013/2010/2007/2003绿色精......
  • 2025-01-13 闲话
    答应杨卓凡不去北京就每天写闲话,但是今天实在不知道能写啥,于是让chatgpt写。然后被逗笑了。穷尽kimideepseek和chatgpt,只有deepseek的联网搜索,最终给了一个有点人样的仿写。可是ai的generation一点也不口语化,入眼的呆滞与死板就像是水印。看来我们的LLMproducts......
  • 代码随想录:最大二叉树
    白送/***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNode*left;*TreeNode*right;*TreeNode():val(0),left(nullptr),right(nullptr){}*TreeNode(intx):val(x),left(nullptr),right(nullptr){}......