代码随想录算法训练营第35天|LeetCode 01背包问题 二维、01背包问题 一维、416. 分割等和子集

news2024/11/15 11:15:35

1. LeetCode 01背包问题 二维

题目链接:https://kamacoder.com/problempage.php?pid=1046
文章链接:https://programmercarl.com/背包理论基础01背包-1.html#算法公开课
视频链接:https://www.bilibili.com/video/BV1cg411g7Y6/

在这里插入图片描述

思路:
01背包问题

  1. 定义dp数组 dp[i][j]表示在0~i物品内任意选择,放入j空间大小的背包中的最大价值
    int[][] dp = new int[M][N+1];
  2. 递推公式
    dp[i][j] =
    Math.max(dp[i-1][j],dp[i-1][j-Integer.valueOf(space[i])]+Integer.valueOf(value[i]))
  3. 初始化
    for (int j=Integer.valueOf(space[0]);j<=N;j++) {
    dp[0][j] = Integer.valueOf(value[0]);
    }
  4. 遍历顺序 先物品再空间

注意:
1️⃣若当前背包的容量都没有当前物品i大的时候,是不放物品i的。那么前i-1个物品能放下的最大价值就是当前情况的最大价值;
2️⃣若当前背包的容量可以放下物品i
那么此时分两种情况:
1、不放物品i
2、放物品i
比较这两种情况下,哪种背包中物品的最大价值最大

import java.util.*;

// 01背包问题
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] firLine = sc.nextLine().split(" ");
        String[] space = sc.nextLine().split(" ");
        String[] value = sc.nextLine().split(" ");
        int M = Integer.valueOf(firLine[0]); // 物品数量
        int N = Integer.valueOf(firLine[1]); // 背包空间
        
        // 1. 定义dp数组 dp[i][j]表示在0~i物品内选择j空间的最大价值
        int[][] dp = new int[M][N+1];
        
        // 2. 递推公式
        // dp[i][j] = Math.max(dp[i-1][j],
        // dp[i-1][j-Integer.valueOf(space[i])]+Integer.valueOf(value[i]))
        
        // 3. 初始化
        for (int j=Integer.valueOf(space[0]);j<=N;j++) {
            dp[0][j] = Integer.valueOf(value[0]);
        }
    
        
        // 4. 遍历顺序 先物品再空间
        for (int i=1;i<M;i++) {
            for (int j=0;j<N+1;j++) {
                if (j < Integer.valueOf(space[i])) {
                    dp[i][j] = dp[i-1][j];
                } else {
                    dp[i][j] = Math.max(dp[i-1][j],
                    dp[i-1][j-Integer.valueOf(space[i])]+Integer.valueOf(value[i]));
                }
            }
        }
        
        System.out.println(dp[M-1][N]);
        
    }
}

2. LeetCode 01背包问题 一维

题目链接:https://kamacoder.com/problempage.php?pid=1046
文章链接:https://programmercarl.com/背包理论基础01背包-2.html#思路
视频链接:https://www.bilibili.com/video/BV1BU4y177kY/

思路:
01背包问题

  1. 确定dp数组的定义
    在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]。
  2. 一维dp数组的递推公式
    dp[j]有两个选择:
    (1)不放物品i:取自己dp[j],相当于 二维dp数组中的dp[i-1][j];
    (2)放物品i:取dp[j - weight[i]] + value[i]。
    dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
  3. 一维dp数组如何初始化
    关于初始化,一定要和dp数组的定义吻合,否则到递推公式的时候就会越来越乱。dp[0]应该是0,因为背包容量为0所背的物品的最大价值就是0。
    除了下标0的位置,假设物品价值都是大于0的,所以dp数组初始化的时候,都初始为0就可以了。
  4. 一维dp数组遍历顺序
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]);
    }// j>=weight[i],即物品i只能放到weight大于该物品重量的背包中。
}// 归根结底,当前物品只可能放入背包重量大于当前物品重量的背包中
import java.util.*;

// // 01背包问题
// // 二维数组
// public class Main {
//     public static void main(String[] args) {
//         Scanner sc = new Scanner(System.in);
//         String[] firLine = sc.nextLine().split(" ");
//         String[] space = sc.nextLine().split(" ");
//         String[] value = sc.nextLine().split(" ");
//         int M = Integer.valueOf(firLine[0]); // 物品数量
//         int N = Integer.valueOf(firLine[1]); // 背包空间
        
//         // 1. 定义dp数组 dp[i][j]表示在0~i物品内选择j空间的最大价值
//         int[][] dp = new int[M][N+1];
        
//         // 2. 递推公式
//         // dp[i][j] = Math.max(dp[i-1][j],
//         // dp[i-1][j-Integer.valueOf(space[i])]+Integer.valueOf(value[i]))
        
//         // 3. 初始化
//         for (int j=Integer.valueOf(space[0]);j<=N;j++) {
//             dp[0][j] = Integer.valueOf(value[0]);
//         }
    
        
//         // 4. 遍历顺序 先物品再空间
//         for (int i=1;i<M;i++) {
//             for (int j=0;j<N+1;j++) {
//                 if (j < Integer.valueOf(space[i])) {
//                     dp[i][j] = dp[i-1][j];
//                 } else {
//                     dp[i][j] = Math.max(dp[i-1][j],
//                     dp[i-1][j-Integer.valueOf(space[i])]+Integer.valueOf(value[i]));
//                 }
//             }
//         }
        
//         System.out.println(dp[M-1][N]);
        
//     }
// }

// 一维数组

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] firLine = sc.nextLine().split(" ");
        String[] space = sc.nextLine().split(" ");
        String[] value = sc.nextLine().split(" ");
        int M = Integer.valueOf(firLine[0]); // 物品数量
        int N = Integer.valueOf(firLine[1]); // 背包空间
        
        // 1. 定义dp数组 dp[j]表示空间j的背包的最大价值
        int[] dp = new int[N+1];
        
        // 2. 递推公式
        // dp[j] = Math.max(dp[j],dp[j-Integer.valueOf(space[i])]+Integer.valueOf(value[i]))
        // 3. 初始化
    
        
        // 4. 遍历顺序 先物品再空间
        for (int i=0;i<M;i++) {
            for (int j=N;j>=Integer.valueOf(space[i]);j--) {
                dp[j] = Math.max(dp[j],dp[j-Integer.valueOf(space[i])]+Integer.valueOf(value[i]));
            }
        }
        
        System.out.println(dp[N]);
        
    }
}

3. LeetCode 416. 分割等和子集

题目链接:https://leetcode.cn/problems/partition-equal-subset-sum/description/
文章链接:https://programmercarl.com/0416.分割等和子集.html
视频链接:https://www.bilibili.com/video/BV1rt4y1N7jE/

在这里插入图片描述

思路:此题是01背包应用类题。
题目中物品是nums[i],重量是nums[i],价值也是nums[i],背包体积是sum/2。
只有确定了如下四点,才能把01背包问题套到本题上来。
1.背包的体积为sum / 2
2.背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
3.背包如果正好装满,说明找到了总和为 sum / 2 的子集。
4.背包中每一个元素是不可重复放入。

解法:
class Solution {
    public boolean canPartition(int[] nums) {
        int sum = 0;
        for (int i=0;i<nums.length;i++) {
            sum += nums[i];
        }
        if (sum%2==1) return false;
        int N = sum/2;

        //1. 定义dp数组 dp[j] 表示 容量j的背包所能获取的最大的物品价值
        // 注意:这里物品的重量=物品的价值。最大的物品价值=最大的物品重量
        int[] dp = new int[N+1];

        //2.递推公式
        //dp[j] = Math.max(dp[j],dp[j-nums[i]]+nums[i]);

        //3.初始化
        //4.遍历顺序 先物品再背包
        for (int i=0;i<nums.length;i++) {
            for (int j=N;j>=nums[i];j--) {
                dp[j] = Math.max(dp[j],dp[j-nums[i]]+nums[i]);
            }
        }

        return dp[N]==N;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1939571.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Vue】`v-if` 指令详解:条件渲染的高效实现

文章目录 一、v-if 指令概述二、v-if 的基本用法1. 基本用法2. 使用 v-else3. 使用 v-else-if 三、v-if 指令的高级用法1. 与 v-for 一起使用2. v-if 的性能优化 四、v-if 的常见应用场景1. 表单验证2. 弹窗控制 五、v-if 指令的注意事项 Vue.js 是一个用于构建用户界面的渐进式…

在 PostgreSQL 里如何实现数据的冷热数据分层存储的自动化策略调整?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 在 PostgreSQL 里如何实现数据的冷热数据分层存储的自动化策略调整 在 PostgreSQL 里如何实现数据的冷…

最新可用度盘不限速后台系统源码_去授权开心版

某宝同款度盘不限速后台系统源码&#xff0c;验证已被我去除&#xff0c;两个后端系统&#xff0c;账号和卡密系统 第一步安装宝塔&#xff0c;部署卡密系统&#xff0c;需要环境php7.4 把源码丢进去&#xff0c;设置php7.4&#xff0c;和伪静态为thinkphp直接访问安装就行 …

bootstrap中文文档官网

Bootstrap v3 中文文档 Bootstrap 是最受欢迎的 HTML、CSS 和 JavaScript 框架&#xff0c;用于开发响应式布局、移动设备优先的 WEB 项目。 | Bootstrap 中文网

PostgreSQL 中如何解决因大量并发删除和插入操作导致的索引抖动?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何解决因大量并发删除和插入操作导致的索引抖动一、理解索引抖动二、索引抖动的影响三…

C语言:温度转换

1.题目&#xff1a;实现摄氏度&#xff08;Celsius&#xff09;和华氏度&#xff08;Fahrenheit&#xff09;之间的转换。 输入一个华氏温度&#xff0c;输出摄氏温度&#xff0c;结果保留两位小数。 2.思路&#xff1a;&#xff08;这是固定公式&#xff0c;其中 F 是华氏度&a…

DL/T645-2007_Part1(协议帧解析)

帧结构 起始字符68H地址域起始字符68H控制码C数据域长度L数据域校验和CS结束字符16H1Byte6Byte1Byte1Byte1ByteN Byte1Byte1Byte 地址域 地址域为6个字节的BCD码构成&#xff0c;当使用的地址码长度不足6字节&#xff0c;高位用0补足&#xff1b;当通信地址为99999999999H时…

自学 阿里巴巴Java开发手册最新版(嵩山版)

&#x1f534; 阿里巴巴Java开发手册最新版&#xff08;嵩山版&#xff09; 一、编程规约(一) 命名风格(二) 常量定义(三) 代码格式(四) OOP 规约(五) 日期时间(六) 集合处理(七) 并发处理(八) 控制语句(九) 注释规约(十) 前后端规范 二、异常日志(一) 错误码(二) 异常处理(三)…

【BUG】已解决:python setup.py bdist_wheel did not run successfully.

已解决&#xff1a;python setup.py bdist_wheel did not run successfully. 目录 已解决&#xff1a;python setup.py bdist_wheel did not run successfully. 【常见模块错误】 解决办法&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主…

自动驾驶-预测概览

通过生成一条路径来预测一个物体的行为&#xff0c;在每一个时间段内&#xff0c;为每一辆汽车重新计算预测他们新生成的路径&#xff0c;这些预测路径为规划阶段做出决策提供了必要信息 预测路径有实时性的要求&#xff0c;预测模块能够学习新的行为。我们可以使用多源的数据…

NetSuite Saved Search迁移工具

我们需要在系统间迁移Saved Search&#xff0c;但是采用Copy To Account或者Bundle时&#xff0c;会有一些Translation不能迁移&#xff0c;或者很多莫名其妙的Dependency&#xff0c;导致迁移失败。因此&#xff0c;我们想另辟蹊径&#xff0c;借助代码完成Saved Search的迁移…

数据库事务隔离级别及底层原理详解

本文详细记录了数据库中事务的隔离级别及其定义&#xff0c;以及每个隔离级别下可能会遇到哪些问题及对应的解决方案和原理&#xff0c;以下内容结合为各大平台的知识点加自己的理解进行的总结&#xff0c;希望大家在读完以后能对事务有个全新的认识~~ 1. MySQL事务管理 自动…

Connecting weaviate with langflow across docker containers

题意&#xff1a;在Docker容器之间连接Weaviate与Langflow 问题背景&#xff1a; I am trying to build a local RAG application using Langflow. For my vectore store, I want to use a local Weaviate instance, hosted in a separate docker container on the same netwo…

使用dock构建基于lnmp的WrodPress

项目要求&#xff1a; 1.创建nginx容器环境 上传nginx.conf文件、上传阿里云镜像、上传html目录 2.准备mysql cd /opt mkdir mysql 上传my.conf文件、上传阿里云镜像、写好的Dockfile文件 3.准备php cd /opt mkdir php 上传所需文件&#xff1a; 构建各镜像&#xff1a; …

【艺术向】【素描创作记录】《如何为你的红颜知己创作一幅画像(之二)》

写在前面 之前分析过类似的创作过程&#xff0c;见博客【艺术向】【素描创作记录】《如何为你的红颜知己创作一幅画像》 本人业余时间修习素描多年&#xff0c;在此撰文记录《如何为你的红颜知己创作一幅画像&#xff08;之二&#xff09;》&#xff0c;博得对方好感&#xff…

JQuery+HTML+JavaScript:实现地图位置选取和地址模糊查询

本文详细讲解了如何使用 JQueryHTMLJavaScript 实现移动端页面中的地图位置选取功能。本文逐步展示了如何构建基本的地图页面&#xff0c;如何通过点击地图获取经纬度和地理信息&#xff0c;以及如何实现模糊查询地址并在地图上标注。最后&#xff0c;提供了完整的代码示例&…

【proteus经典实战】LCD滚动显示汉字

一、简介 Proteus是一款功能丰富的电子设计和仿真软件&#xff0c;它允许用户设计电路图、进行PCB布局&#xff0c;并在虚拟环境中测试电路功能。这款软件广泛应用于教育和产品原型设计&#xff0c;特别适合于快速原型制作和电路设计教育。Proteus的3D可视化功能使得设计更加直…

Elasticsearch ILM 热节点迁移至冷节点 IO 打满、影响读写解决方案探讨

1、实战问题 ILM&#xff08;索引生命周期管理&#xff09; 遇到热数据迁移至冷节点时造成 IO 打满影响读写的情况。 现在采取的方案是调整索引生命周期策略&#xff0c;定时的将Cold phase 开启/关闭。低峰开启&#xff0c;高峰关闭。 就是不知道这里面会有啥坑。 热节点&…

C++笔试强训7

文章目录 一、选择题1-5题6-10题 二、编程题题目一题目二 一、选择题 1-5题 基础知识&#xff0c;函数代码少&#xff0c;频繁调用的时候才适合定义内联函数。 故选C。 在C中&#xff0c;inline关键字是用来向编译器建议将函数体在每个调用点“内联展开”的。这意味着编译器会…

意得辑润色极致优惠方案

祝审稿人们编辑们及他们全家工作顺利身体健康万事如意心想事成&#x1f647;&#x1f3fb;&#x1f647;&#x1f3fb;&#x1f647;&#x1f3fb; 好人一生平安&#x1f64f;&#x1f3fb;&#x1f64f;&#x1f3fb;&#x1f64f;&#x1f3fb; #accept