【二维费用的完全背包问题】

2023-11-10

前言

简单写一下算法设计与分析这门课的一次实验
3-10
原题要求是用0-1背包来做,但是老师要求用完全背包来做!

一、完全背包与0-1背包有什么区别?

0-1背包,顾名思义对于每件物品只能拿1次或者0次;而完全背包对于每件物品的拿取没有次数限制。

二、二维费用背包

二维费用背包是对于每件物品的拿取要付出两项代价,如:重量和体积。

三、0-1背包

理解0-1背包对我们理解其他背包问题十分重要,首先说一下0-1背包。
问题描述:
有n件物品,背包的最大承重是W,每个物品的重量是c[i],价值为v[i];定义状态f[i][w]为当前包内的可承重为w时,在前i件物品内选取得到的最大价值;
对于状态f[i][w]有两种选择:

  1. 在背包当前承重允许的情况下选择第i件物品,那么原问题规约为在前i-1件物品选取得到重量不超过w-c[i]的最大价值的子问题,此时f[i][w]=f[i-1][w-c[i]]+v[i];
  2. 不选择第i件物品,那么原问题规约为在前i-1件物品中选取得到重量不超过w的最大价值的子问题,此时f[i][w]=f[i-1][w];

所以可以得到相应的状态转移方程:

f[i][w]=max(f[i-1][w],f[i-1][w-c[i]+v[i])

所以可以得到0-1背包问题的核心代码:

for(int i=1;i<=n;i++){
	for(int w=c[i];w<=W;w++){
	f[i][w]=max(f[i-1][w],f[i-1][w-c[i]]+v[i]);
	}
}

这里时间与空间复杂度均为O(V*n);时间复杂度已经无法继续优化,但空间复杂度可以。通过观察发现,类似滚动数组原理,可以将f[i][w]压缩成f[w]的一维数组,只需要维护这样的一维数组即可。
所以上面代码变成下面这样:

for(int i=1;i<=n;i++){
	for(int w=W;w>=c[i];w--){
	f[w]=max(f[w],f[w-c[i]]+v[i]);
	}
}

相信已经有小伙伴发现了这两段代码的区别不仅仅是数组了。第一段代码中第二层循环是正序的,而第二段代码中第二层循环变成逆序了。这里便是需要注意的地方。下面将给出说明:
当f是二维数组时,不管f[i][w]做出哪种选择都依赖上一行i-1行的结果,这时只要直接获取即可。当f为一维数组时,此时f数组还未刷新即对应二维数组i-1行,如果循环是顺序的话,当f[w]刷新后,如果后面的f[w’]需要i-1行的f[w]时,此时f[w]已经是i行的f[w],那么就会出错,因此需要逆序循环,这时候需要访问的f[w]都是未刷新前的。

四、完全背包

完全背包与0-1背包的区别已经说过,不再赘述。
对于f[i][w]有两种选择:

  1. 不选择当前的第i件物品,原问题规约为在前i-1件物品中选取,此时f[i][w]=f[i-1][w];
  2. 选择当前第i件物品,原问题规约为在前i件物品中选取,此时f[i][w]=f[i][w-c[i]]+v[i];

f[i][w]=max(f[i-1][w],f[i][w-c[i]]+v[i])

这里直接给出压缩成一维数组后的核心代码

for(int i=1;i<=n;i++){
	for(int w=c[i];w<=W;w++){
	f[w]=max(f[w],f[w-c[i]]+v[i]);
	}
}

这里的第二层循环为什么是正序。这里做出解释:因为完全背包的特点,当选择第i件物品时,问题会变成在前i件物品中选取,不会变成0-1背包那样在前i-1件物品中选取,因此当计算f[w]时可能需要当前已经刷新后的f[w’],即第i行的数据。

五、二维费用的完全背包问题

回到本次实验:
本次实验是二维费用下的完全背包问题。与一维相比也就是多了一层循环。该实验的完整代码如下:

//定义物品数据结构 
struct item{
    int w;//重量
    int c;//体积
    int v;//价值
}; 

int KnapsackProblem(item x[],int n,int W,int V){//物品数组,物品数量,重量上限,体积上限
                         
    //初始化
    dp[0][0]=0;
    for(int i=1;i<=n;i++){
        for(int w=x[i].w;w<=W;w++){
            for(int c=x[i].c;c<=V;c++){
            dp[w][c]=max(dp[w][c],dp[w-x[i].w][c-x[i].c]+x[i].v);
		    }   
        }
	}
    return dp[W][V];
}

KnapsackProblem()函数的时间复杂度为O(nVW);

小结

关于背包问题有很多人的讲解。这是笔者第一次写博客,主要是自己的一些理解,如果有错误的地方希望能够给予指正。如果有其他建议也可以添加笔者的QQ:2736664064进行交流。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【二维费用的完全背包问题】 的相关文章

  • 【华为OD机试真题 python】查找重复代码【2022 Q4

    题目描述 查找重复代码 小明负责维护项目下的代码 需要查找出重复代码 用以支撑后续的代码优化 请你帮助小明找出重复的代码 重复代码查找方法 以字符串形式给定两行代码 字符串长度 1 lt length lt 100 由英文字母 数字和空格组
  • 模糊匹配之——BK树与拼写纠正

    介绍 拼写纠错功能常常出现在比较高级的文本编辑应用中 例如大家熟知的word 高级一点的IDE例如Jet Brains系列 在一些在线翻译上 也有自动校正拼写的功能 例如谷歌翻译 原理 拼写纠正的实现方式有多种 这里使用的是一种名为BK树的
  • Python实现找零兑换的三种解法

    找零兑换 找零兑换问题最直接的解法就是贪心策略 比如问题 有面值1 5 10 25的硬币 求解兑换63元所需的最少硬币数 贪心策略的思想就是不断的利用面值最大的硬币去尝试 不行了 在尝试较小面值的硬币 该例中也即使用25的硬币去尝试 2枚2
  • 第十四届蓝桥杯模拟赛(第三期)试题与题解 C++

    目录 一 填空题 一 最小的十六进制 答案 2730 二 Excel的列 答案 BYT 三 相等日期 答案 70910 四 多少种取法 答案 189 五 最大连通分块 答案 148 二 编程题 一 哪一天 二 信号覆盖 三 清理水草 四 最
  • 刷题之搜索插入位置

    给定一个排序数组和一个目标值 在数组中找到目标值 并返回其索引 如果目标值不存在于数组中 返回它将会被按顺序插入的位置 请必须使用时间复杂度为 O log n 的算法 来源 力扣 LeetCode 链接 https leetcode cn
  • LeetCode312. 戳气球 (分治,记忆化搜索,动态规划)

    LeetCode312 戳气球 解题思路 记忆化搜索 动态规划 解题思路 官方题解 参考题解 核心思想 由于戳气球的操作会导致两个气球从不相邻变成相邻 使得后续操作难以处理 于是我们倒过来看这些操作 将全过程看成每次添加一个气球 solve
  • [HDU 5079][2014 Asia AnShan Regional Contest]Square(DP套DP)

    题目链接 http acm hdu edu cn showproblem php pid 5079 题目大意 给你一个 n n n 8 n middot n n le 8 的棋盘 上面有一些格子必须是黑色 其它可以染黑或者染白 对于一个棋盘
  • 试除法判定质数模板题

    试除法判定一个数是否为质数类似于这道题 代码 include
  • 动态规划算法解决背包问题(Java实现)

    文章收藏的好句子 你在书本上花的任何时间 都会在某一个时刻给你回报 目录 1 动态规划算法的概述 2 背包问题 3 动态规划算法解决背包问题 3 1 不可重复装入商品 3 2 思路分析 1 动态规划算法的概述 1 动态规划算法的思想是 将大
  • 最近在学动态规划,很有意思的算法(1)拿金币

    问题描述 有一个N x N的方格 每一个格子都有一些金币 只要站在格子里就能拿到里面的金币 你站在最左上角的格子里 每次可以从一个格子走到它右边或下边的格子里 请问如何走才能拿到最多的金币 输入格式 第一行输入一个正整数n 以下n行描述该方
  • 哈夫曼编解码算法(C实现)

    记得在毕业前去找工作 应聘康佳集团移动应用工程师的笔试题出了这么一道题 传输文本字符 BADCADFEED 只能出现 ABCDEF 这六个字符 使用以下的编码方式 如传输字符 BADCADFEED 接收编码 0010000110100000
  • 最短Hamilton路径

    题目 题目链接 题解 状压dp f i j 表示从0点按照路径i走到j点的最短距离 其中i为二进制数 1表示走过某点 0表示未走过某点 比如10010表示经过了1 4两个点 而不经过0 2 3点 状态转移为 假设沿路径i走到j点经过k点 且
  • 用递归法求两个数的最大公约数

    用递归法求两个数的最大公约数 求两个数的最大公约数的思路是 用辗转现除法 辗转相除法求两个数的最大公约数的步骤如下 先用小的一个数除大的一个数 得第一个余数 再用第一个余数除小的一个数 得第二个余数 又用第二个余数除第一个余数 得第三个余数
  • 0动态规划中等 NC206 跳跃游戏(二)

    NC206 跳跃游戏 二 描述 给定一个非负整数数组nums 假定最开始处于下标为0的位置 数组里面的每个元素代表下一跳能够跳跃的最大长度 如果可以跳到数组最后一个位置 请你求出跳跃路径中所能获得的最多的积分 1 如果能够跳到数组最后一个位
  • C++---背包模型---装箱问题(每日一道算法2023.3.9)

    注意事项 本题是 动态规划 01背包 的扩展题 dp和优化思路不多赘述 题目 有一个箱子容量为 V 同时有 n 个物品 每个物品有一个体积 正整数 要求 n 个物品中 任取若干个装入箱内 使箱子的剩余空间为最小 输入格式 第一行是一个整数
  • 《算法图解》——第八章 贪婪算法

    第八章 贪婪算法 1 简单的贪婪算法 每步都采取最优的做法 每步都选择局部最优解 2 背包问题 有些情况下 完美是优秀的敌人 如果你只需要找到一个大致解决问题的算法 贪婪算法挺不错 因为实现容易 结果与正确结果相当接近 练习8 1 你在一家
  • Thief in a Shop 【CodeForces - 632E】【背包】

    题目链接 给了N个物品 每个物品无限个 我们要的是求刚好我们拿了K个物品的时候 能组成哪几种数 我们可以想个办法去填充 那么就需要有一个所谓的0状态 然后假如不足K个的时候 就可以拿这个所谓的0状态来填充了 所以 我们把所有的数排序 然后都
  • HJ103 Redraiment的走法

    Redraiment是走梅花桩的高手 Redraiment可以选择任意一个起点 从前到后 但只能从低处往高处的桩子走 他希望走的步数最多 你能替Redraiment研究他最多走的步数吗 示例 2 5 1 5 4 5 输出 3 说明 6个点的
  • 《算法图解》第九章动态规划学习心得

    1 背包问题 动态规划先解决子问题 再逐步解决大问题 每个动态规划都从一个网格开始 背包问题的网格如下 网格最初是空的 动态规划就是逐步将网格填满 吉他行 第一个单元格表示背包的容量为1磅 吉他的重量也是1磅 这意味着它能装入背包 因此这个
  • 算法竞赛当中的思考方法——方法论篇。

    方法论 万物皆朴素的第一性原理 几乎任何领域的任何问题的解决方案 都可以看作是 某个结构上的朴素方法的优化 计算机只能处理规模有限的问题 在给定规模且不考虑效率的情况下 问题一定存在朴素解法 具体手段有直接模拟 利用bit枚举 各种搜索算法

随机推荐

  • 处理el-table大数据卡顿的问题,包含tree型数据格式

    文章目录 概要 技术细节 小结 概要 如果你有更丰富的表格需求 可以查看我另一篇文章 关于vxe table的使用心得及扩展 1 现象 有时候el table的数据可能有成千上万条 而且又要在一页显示完 这时候页面渲染的dom太多了 可能会
  • Java如何保证集合是线程安全的?(代码实践抛砖引玉)

    在Java中绝大部分的集合像什么ArrayList HashMap等绝大部分不是线程安全的 仅有的线程安全的实现 像HashTable Vector等在性能上又不好 但是不要怕啊 我们大Java还有并发包 Java util concurr
  • (汇编:20H~7FH 单元数据清0)

    函数功能 20H 7FH 单元数据清0 ORG 000H 从000H单元开始 MOV A 02H 把1赋值给寄存器A MOV R1 20H 清零数据首地址为20H MOV R2 60H 需要置1的次数 LOOP MOV R1 A 采用间接寻
  • 【postgres】备份还原数据库

    备注 数据库密码都是一个 su postgres 导出数据库 pg dump p 15432 数据库名 gt 备份名 sql 创建数据库 su root psql p 15432 U postgres W 注意一定要加 号 create d
  • eclipse生成webservice客户端代码以及通过客户端访问服务端

    最近工作中需要用到webservice调用其他服务 没接触过这个 研究了几天 做个记录 1 eclipse生成webservice客户端 打开eclipse File gt gt New gt gt Other 2 Web Services
  • MySQL 复制数据到另外一张表(新建空表、已建空表)

    一 仅复制表结构到新建表 说明 example new为新创建表 example old为旧表 操作完成后仅把旧表结构复制到新建表 create table example new like example old 二 复制结构与数据到新建
  • 翁凯c语言作业10-1

    include
  • 搭建一个简单的https服务

    为了测试ab工具压测https接口 简单搭了一下https 记录一下过程 环境准备 在docker中建了3个容器 A 证书颁发 CA B 服务端 C 客户端 docker run d name ca centos centos7 bin b
  • mac解决mysql忘记密码的问题(亲测有效)

    打开终端依次执行如下命令 第一步 进入mysql服务 sudo usr local mysql support files mysql server stop 第一步 进入mysql的bin目录 cd usr local mysql bin
  • nginx多级代理

    文章目录 一 实验步骤 1 docker config创建3台nginx配置文件 2 集群node节点打标签 3 docker compose编排文件 4 在manager节点创建目录 5 部署服务 6 访问测试 总结 测试环境说明 基于d
  • 解决git:fatal:Unable to create".../.git/index.lock" 的错误

    问题描述 在使用git 进行提交时 出现上面这个报错 导致无法提交 报错大致意思就是创建index lock文件失败 因为已经存在index lock文件了 index lock文件是在 git下面 而 git是一般是隐藏的 那么可以通过以
  • std::enable_shared_from_this消除异步回调引发的野指针问题

    std enable shared from this这个C 组件完美解决了异步回调发生时宿主对象销毁的问题 C 提供了lambda表达式和各种异步函数 std thread std async或者其他框架api都提供了异步回调方法 特别是
  • js实现数组去重、比较两数组得出重复部分

    数组去重的两种方法 1 用新对象来存储 对象的key值为数组元素 var removeDup function old var arr 1 2 3 4 3 4 5 var o for var i 0 i lt arr length i va
  • Android MVC MVP MVVM

    浅谈 MVP in Android MVP模式解析实践 Android DataBinding库 MVVM设计模式
  • 浏览器兼容性测试工具

    相关连接 浏览器兼容性概述 目录 一 浏览器兼容性测试工具 1 0 IETester 免费 exe 1 1 SuperPreview 收费 exe 1 2 Adobe Browserlab 在线测试 1 3 BrowserStack 在线测
  • 从HTTP 2.0想到的关于传输层协议的一些事

    0 HTTP协议的历史我也不知道 1 关于HTTP 2 0收到了订阅的邮件 头版是说HTTP 2 0的内容 我本人不是很关注HTTP这一块儿 但是闲得无聊时也会瞟两眼的 HTTP 2 0的最大改进我觉得有两点 第一 新增了帧层 帧层的好处在
  • ThinkPHP3.2微信JSSDK签名配置config信息

    ThinkPHP3 2 controller代码 微信jssdk踩坑记 必须在服务器部署才有用 1 配置js接口安全域名不要加http 等 大坑 2 用appid和appsecret发起请求换取access token并将其全局缓存 3 用
  • 发布自己写的python包(得瑟)

    如何把自己写的包发布到pipy给别人用呢 网上一堆教程 众所周知网上教程都比较长 得耐心看完 学会了消化之后变成自己的了记录一下 第一步包的目录结构 抄作业就完了 第二步设置setup py 有个for human的模板 老哥起名也是幽默
  • adb shell dumpsys 使用命令和来源

    一 概述 adb shell dumpsys 在Android开发中经常要用到 平时都是零碎的积累 用到什么的时候就 记录下来 最近看了一些资料 发现可以汇总所有的命令 当带某个参数的时候 就可以查看具体 的信息 本篇文章中还讲解了如何去找
  • 【二维费用的完全背包问题】

    前言 简单写一下算法设计与分析这门课的一次实验 原题要求是用0 1背包来做 但是老师要求用完全背包来做 一 完全背包与0 1背包有什么区别 0 1背包 顾名思义对于每件物品只能拿1次或者0次 而完全背包对于每件物品的拿取没有次数限制 二 二