算法-背包问题

问题描述

假设我有一个背包,希望在装得下的情况下,尽量装进价值更多的物品。那么我该怎么做呢?

问题抽象

假设背包的容量是m,就假设是4吧

# 表示背包容量4KG
m = 4 

可选装进背包的物品有n个,物品的价值存储在prices里,重量存储在weight里

# 表示有3个物品可以选,分别价值是1500 3000 2000
prices = [1500, 3000, 2000]
# 物品重量分别是1kg 4kg 3kg
weight = [1, 4, 3]

显然,我们的目的是填满以下价值矩阵,res[i][j]表示在可选物品有i个的情况下,背包容量在j容量的情况下的最优解:

# 我们需要填满这个n 行 m列的矩阵
res = [[0] * m for _ in range(n)]
物品价值和重量物品\背包容量1234
1500元 1kg物品1
3000元 4kg物品1、物品2
2000元 3kg物品1/2/3

求解过程

显然,第一行是最好求解的。当只有1个物品可选时,只要装得下,只能装它。所以第一行全是1500元。

物品价值和重量物品\背包容量1234
1500元 1kg物品11500150015001500
3000元 4kg物品1、物品2
2000元 3kg物品1/2/3

当可选物品变成2个时,显然,由于物品2的重量是4KG,背包容量小于4的情况下,全都放不下,于是只有在背包容量达到4的时候,可以放一个物品2,这个格子的最优解是3000

物品价值和重量物品\背包容量1234
1500元 1kg物品11500150015001500
3000元 4kg物品1、物品21500150015003000
2000元 3kg物品1/2/3

当可选物品变成3个的时候,在背包容量3的时候,可以选择物品3了,所以这一个格子的值是2000

物品价值和重量物品\背包容量1234
1500元 1kg物品11500150015001500
3000元 4kg物品1、物品21500150015003000
2000元 3kg物品1/2/3150015002000

最后一个格子比较特殊,我们来分别考虑

  1. 如果背包容量-当前最新物品的重量>0,说明还能装其他东西,所以这一个格子可能值是:

    当前物品价值+ 上一行的 剩余背包容量最优解。再拿这个值,和上一行的该列比较,大的那个就是最优解

    # 注意这里j+1,是因为是j从0开始,而背包容量从1开始
    prices[i] + res[i-1][j+1-weight[i]]
    # 
    res[i][j] = max(res[i-1][j], prices[i] + res[i-1][j+1-weight[i]])
    
  2. 如果背包容量-当前最新物品的重量=0,那么说明这时候只能装它了。最优解就是新物品重量和上一行比,大的那一个

    res[i][j] = max(res[i - 1][j], prices[i])
    
  3. 如果背包容量-当前最新物品的重量<0,那么说明新物品对这个格子没有影响,还是取上一行的值

    res[i][j] = res[i-1][j]
    

经过一番比较,我们可以知道这个格子最优是2000加上上一行的容量为1时的值

物品价值和重量物品\背包容量1234
1500元 1kg物品11500150015001500
3000元 4kg物品1、物品21500150015003000
2000元 3kg物品1/2/31500150020003500

最终代码

经过上面的举例,可以看出,大部分格子都遵循这三种情况。除了第一行,因为没法和上一行比较。最终代码如下:

def max_bag(n: int, m: int, weight: list[int], prices: list[int]):"""背包问题:param n: 可选物品总数量,矩阵的行:param m: 背包总重量,矩阵的列:param weight: 物品重量列表:param prices: 物品价格列表:return: 返回最大价值"""res = [[0] * m for _ in range(n)]# 第一行for j in range(m):if j + 1 - weight[0] >= 0:res[0][j] = prices[0]else:res[0][j] = 0for i in range(1, n):for j in range(m):# 大于零说明装了当前商品之后还有空位,那么最大值就是在res[i-1][j]和#  当前价值prices[i] + 剩余格子价值# 这两者之间取最大值if j + 1 - weight[i] > 0:res[i][j] = max(res[i-1][j],  prices[i] + res[i-1][j+1-weight[i]])# 等于0,说明刚好能装这一个物品,所以最大值是要么上一行的这个格子,要么就是当前商品价值elif j + 1 - weight[i] == 0:res[i][j] = max(res[i - 1][j], prices[i])# 如果小于0,那就还是取上一行的else:res[i][j] = res[i-1][j]print(res)return res[n-1][m-1]

可以用如下输入来验证结果:

my_n = 3
my_m = 4
my_weights = [1, 4, 3]
my_prices = [1500, 3000, 2000]
print(max_bag(my_n, my_m, my_weights, my_prices))

本文参考了:https://blog.csdn.net/bohu83/article/details/91453227

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

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

相关文章

支付宝手机网站支付,微信扫描二维码支付

支付宝手机网站支付 支付宝文档 响应示例 <form name"punchout_form" method"post" action"https://openapi.alipay.com/gateway.do?charsetUTF-8&methodalipay.trade.wap.pay&formatjson&signERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE…

Maven打包时报错:Cannot allocate memory

使用Jenkins执行Maven打包任务时报错 Cannot allocate memory解决办法&#xff1a; 配置系统变量 MAVEN_OPTS-Xmx256m -XX:MaxPermSize512m或者 在项目目录下新建文件 .mvn/jvm.config -Xmx256m -Xms256m -XX:MaxPermSize512m -Djava.awt.headlesstrue参考 Jenkins Maven …

MySQL 数据库设计范式

第一范式&#xff08;1NF&#xff09; 每一列都是不可分割的原子数据项第二范式&#xff08;2NF&#xff09; 在1NF的基础上&#xff0c;非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖) 1.函数依赖A->B&#xff0c;如果通过A属性(属性组)的值…

Transformer学习【从零理解】

Transformer 一、整体框架 二、Encoder 1.输入部分: &#xff08;1&#xff09;Embedding&#xff1a;将输入的词转换为对应的词向量。 &#xff08;2&#xff09;位置编码&#xff1a;因为保证输出时&#xff0c;顺序不会打乱&#xff0c;所以要加入时序信息即位置编码。 公…

如何避免AI网红经济泡沫?警惕细分行业的AI转型而不是转行

一、AI泡沫预防针 要避免AI相关新概念催生的网红经济泡沫&#xff0c;可以从多个角度采取措施&#xff1a; 1. **理性投资**&#xff1a; - 投资者应对AI项目和网红经济中的企业进行深入研究&#xff0c;了解其真实的技术实力、商业模式的可行性和盈利能力&#xff0c;而非…

代码随想录Day52:最长递增子序列、最长连续递增序列、最长重复子数组

最长递增子序列 class Solution { public:int lengthOfLIS(vector<int>& nums) {if(nums.size() < 1) return nums.size();vector<int> dp(nums.size(), 1);int res 0;for(int i 1; i < nums.size(); i){for(int j 0; j < i; j){if(nums[i] > …

初识GO语言

是由google公司推出的一门编程语言&#xff0c;12年推出的第一个版本 Go的特点 Go为什么能在最近的IT领域炙手可热 集python简洁&C语言的性能于一身 21世纪的C语言 顺应容器化时代的到来 区块链的崛起 学习一门编程语言可以划分为下面这三个步骤 安装 编译器 or 解…

JAVA多线程之synchronized锁

文章目录 1. 临界区2. synchronized使用2.1 不加锁实现2.2 synchronized加锁2.3 面向对象的改进2.4 方法上加synchronized2.5 线程安全 3. Monitor3.1 Java对象头3.2 Monitor工作流程3.3 字节码角度 4. synchronized原理4.1 轻量级锁4.2 锁膨胀4.3 偏向锁4.3.1 偏向锁过程4.3.2…

【链表】Leetcode 2. 两数相加【中等】

两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c; 并且每个节点只能存储 一位 数字。请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外&#xff0c;这两个数都不…

Redis数据结构对象中的对象共享、对象的空转时长

对象共享 概述 除了用于实现引用计数内存回收机制之外&#xff0c;对象的引用计数属性还带有对象共享的作用。 在Redis中&#xff0c;让多个键共享同一个值对象需要执行以下两个步骤: 1.将数据库键的值指针指向一个现有的值对象2.将被共享的值对象的引用计数增一 目前来说…

pytorch 实现线性回归(Pytorch 03)

一 从零实现线性回归 1.1 生成训练数据 原始 计算公式&#xff0c; 我们先使用该公式生成一批数据&#xff0c;然后使用 结果数据去计算 计算 w1, w2 和 b。 %matplotlib inline import random import torch from d2l import torch as d2ldef synthetic_data(w, b, num_ex…

敏捷开发最佳实践:质量维度实践案例之接口级自动化测试

本次分享我们将继续给大家带来全新的质量维度实践案例&#xff1a;接口级自动化测试。 本实践节选自《2022中国企业敏捷实践白皮书》&#xff0c;分享者为查俊&#xff0c;是来自腾讯的高级研发项目经理。 问题&#xff1a; 版本持续迭代&#xff0c;关键路径上的场景持续增…

C#面:简述 var 和 dynamic

var 关键字&#xff1a; var 关键字是在编译时进行类型推断的。也就是说&#xff0c;编译器会根据变量的初始化表达式来确定变量的类型&#xff0c;并在编译时将其替换为实际的类型。var 关键字只能用于局部变量&#xff0c;不能用于字段、方法参数或返回类型。var 关键字声明…

基于springboot+vue的餐饮管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

抖音商城小店电话采集使用教程

下面是一个简单的Python代码示例&#xff0c;用于抓取抖音商城小店的电话号码&#xff1a; import requests import jsondef get_phone_numbers(url):headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3…

Java学习笔记21——使用JDBC访问MySQL数据库

JDBC&#xff08;Java Database Connectivity&#xff0c;Java数据库连接&#xff09;是应用程序编程借口&#xff08;API&#xff09;&#xff0c;描述了一套访问关系数据库的标准Java类库。可以在程序中使用这些API&#xff0c;连接到关系数据库&#xff0c;执行SQL语句&…

IDEA Git恢复DropCommit删除的提交

刚刚Dorp commit了&#xff0c;本地代码也被删除了&#xff0c;如何恢复呢&#xff0c; 从项目中登录git&#xff0c;找到刚刚的commit代码&#xff0c;如下所示&#xff1a;输入命令git reflog 复制代码&#xff0c;到idea中&#xff0c;打开GIt&#xff0c;找到RESET HEAD, …

rust学习笔记(8-12)

8 集合 Rust 标准库中包含一系列被称为 集合&#xff08;collections&#xff09;的非常有用的数据结构。大部分其他数 据类型都代表一个特定的值&#xff0c;不过集合可以包含多个值。不同于内建的数组和元组类型&#xff0c;这些 集合指向的数据是储存在堆上的&#xff0c;这…

Redis:什么是redis?①

一、思想 Redis是一个开源的高性能基于内存key-value数据库&#xff0c;常用作数据库、缓存或消息代理 二、数据类型 String List

初始 Navicat BI 工具

早前&#xff0c;海外 LearnBI online 博主 Adam Finer 对 Navicat Charts Creator 这款 BI&#xff08;商业智能&#xff09;工具进行了真实的测评。今天&#xff0c;我们来看下他对 Navicat BI 工具的初始之感&#xff0c;希望这能给用户一些启发与建议。LearnBI online 作为…