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

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(使用前将#替换为@)

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

  • 贪心(acwing)

    每次选择当前的最优解 没什么固定的套路 先试一些做法 举例子验证 尝试证明一下 严格地推 区间问题 例1 1 将每个区间按照右端点从小到大排序 2 从前往后依次枚举每个区间 如果当前区间已经包含点 则直接pass 否则选择当前区间的右端点
  • 删除与获得点数--动态规划

    Leetcode 740 删除与获得点数 题目描述 给定一个整数数组 nums 你可以对它进行一些操作 每次操作中 选择任意一个 nums i 删除它并获得 nums i 的点数 之后 你必须删除每个等于 nums i 1 或 nums i
  • 每日一题:路径计数

    路径计数 题目 Daimayuan Online Judge f i j 表示从左上角走到 i j 的方案数 状态转移 i j 由 i 1 j 和 i j 1 转移而来 初始状态 得使得f 1 1 为1 所以初始化f 1 0 或者f 0 1
  • 国王和金矿问题

    国王和金矿问题 描述 有一个国家发现了max n座金矿 参与挖矿工人的总数是max people人 每座金矿的黄金储量不同为一维数组gold 需要参与挖掘的工人数也不同为一维数组peopleNeed 每座金矿要么全挖 要么不挖 不能派出一半
  • 【类】二维dp:动态规划背包问题

    dp n m 含义就是 当有n种物品时且背包有m容量时 这个背包能产生的最大价值 状态转换关系是 dp n m dp n 1 m dp n 1 m 新物品重量 意思就是 当面对新来的一个物品时 求这个情况下 背包能产生的最大价值 相当于求下
  • LeetCode64. 最小路径和

    题目大意 求出从网络左上角到右下角的一条代价最小的路径和 题目分析 使用动态规划 求出左上角到网络中每个点的代价最小路径和 假设当前要求的是point i j 点 那么它的值就应该是从左上角到它上面那个点point i 1 j 的路径和 与
  • 试除法判定质数模板题

    试除法判定一个数是否为质数类似于这道题 代码 include
  • 数组的对数器

    原创是某客的左程云老师 我只是加了点自己的注释记个笔记 package basic class 01 import java util Arrays 对数器的作用 对数器可以验证算法是否正确 在比赛或者笔试的时候 如果需要大量的测试用例 而
  • 力扣动态规划专题(一)背包理论基础 基础动规题 动规注意点 步骤及C++实现

    文章目录 动态规划 509 斐波那契数 五步骤 代码 70 爬楼梯 五步骤 代码 746 使用最小花费爬楼梯 五步骤 代码 扩展 62 不同路径 动态规划 数论 63 不同路径 II 五步骤 代码 343 整数拆分 五步骤 代码 96 不同
  • 动态规划算法解决背包问题(Java实现)

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

    问题描述 有一个N x N的方格 每一个格子都有一些金币 只要站在格子里就能拿到里面的金币 你站在最左上角的格子里 每次可以从一个格子走到它右边或下边的格子里 请问如何走才能拿到最多的金币 输入格式 第一行输入一个正整数n 以下n行描述该方
  • POJ-1458最长公共子序列

    给定序列的子序列是给定序列 其中遗漏了一些元素 可能没有 给定序列X
  • 【数据结构】【王道408】——PPT截图与思维导图

    自用视频PPT截图 视频网址王道B站链接 23考研 408新增考点 并查集 红黑树 2023年408真题数据结构篇 408考纲解读 考纲变化 目录 第一章 绪论 第二章 线性表 顺序表 单链表 双链表 循环链表 静态链表 差别 第三章 栈
  • LeetCode338. 比特位计数

    题目连接 https leetcode cn com problems counting bits 解题思路 这道题需要计算从 0 到 num 的每个数的二进制表示中的 1 的数目 最直观的方法是对每个数直接计算二进制表示中的 1 的数目
  • 学习动态规划-子矩阵

    1 全为1的最大正方形 在一个由 0 和 1 组成的二维矩阵内 找到只包含 1 的最大正方形 并返回其面积 来源 221 最大正方形 解题思路 dp i j 表示以matrix i j 为右下角的全1的正方形的最大边长 很明显 当matri
  • leetcode-712. 两个字符串的最小ASCII删除和

    712 两个字符串的最小ASCII删除和 题目 给定两个字符串s1 和 s2 返回使两个字符串相等所需删除字符的 ASCII 值的最小和 示例1 输入 s1 sea s2 eat 输出 231 解释 在 sea 中删除 s 并将 s 的值
  • 动态规划之多重背包模型

    前置知识 01背包问题 动态规划之01背包模型 如何何何的博客 CSDN博客 完全背包问题 动态规划之完全背包模型 如何何何的博客 CSDN博客 多重背包问题 给定一个有一定容量的背包 和 n 个物品 每个物品有 si 件 每个物品有其对应
  • 雪糕的最大数量 排序+贪心

    雪糕的最大数量 雪糕的最大数量 题目描述 样例 数据范围 思路 代码 题目描述 夏日炎炎 小男孩 Tony 想买一些雪糕消消暑 商店中新到 n 支雪糕 用长度为 n 的数组 costs 表示雪糕的定价 其中 costs i 表示第 i 支雪
  • 《算法通关村——滑动窗口高频问题之**寻找子串异位词**》

    算法通关村 滑动窗口高频问题之 寻找子串异位词 567 字符串的排列 给你两个字符串 s1 和 s2 写一个函数来判断 s2 是否包含 s1 的排列 如果是 返回 true 否则 返回 false 换句话说 s1 的排列之一是 s2 的 子
  • 算法设计与实现--动态规划篇

    什么是动态规划算法 动态规划算法是一种求解复杂问题的方法 通过将原问题分解为相对简单的子问题来求解 其基本思想是将待求解的问题分解为若干个子问题 阶段 按顺序求解子阶段 前一子问题的解 为后一子问题的求解提供了有用的信息 在求解任一子问题时

随机推荐

  • 处理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次 而完全背包对于每件物品的拿取没有次数限制 二 二