01背包问题的跳跃点解法

  • 解法分析
  • 代码实现

解法分析

m(i,j)=max{m(i−1,j),m(i−1,j−w[i])+v[i]}m(i,j) = max\{m(i-1,j) , m(i-1,j-w[i])+v[i]\}m(i,j)=max{m(i−1,j),m(i−1,j−w[i])+v[i]}
m(i,j)代表余量j从第一个物品到第i个物品的最优价值m(i,j)代表余量j从第一个物品到第i个物品的最优价值m(i,j)代表余量j从第一个物品到第i个物品的最优价值
p(i)代表m(i,j)的跳跃点点集p(i)代表m(i,j)的跳跃点点集p(i)代表m(i,j)的跳跃点点集
q(i)代表m(i,j−w[i])+v[i]的跳跃点点集合q(i)代表 m(i,j-w[i])+v[i]的跳跃点点集合q(i)代表m(i,j−w[i])+v[i]的跳跃点点集合

备注
1.其中其中其中q(i)可由p(i)的每一个点加上(w[i],v[i])得到。可由p(i)的每一个点加上(w[i],v[i])得到。可由p(i)的每一个点加上(w[i],v[i])得到。
2.p(i−1)并上q(i−1)然后减去必然不合法的点(同w下v非最大的点和w较大但是v较小)即为p(i)p(i-1)并上 q(i-1)然后减去必然不合法的点(同 w 下 v 非最大的点和w较大但是v较小)即为 p(i)p(i−1)并上q(i−1)然后减去必然不合法的点(同w下v非最大的点和w较大但是v较小)即为p(i)

代码实现

具体代码实现的注意事项:
使用一维表table[]加head[]来表示二维表
head[i]:表示第i个行的开端。
其中在pass不合法的点对时,对于q和p中的值采用的方法不一致。具体看代码注释

 const int N = 1e4, M = 1e6;struct Data{int w, v;Data(int nw = 0, int nv = 0) :w(nw), v(nv) {}//构造函数,默认w,v都为0Data operator +(const Data& r)const//设计data结构体的+操作{return Data(w + r.w, v + r.v);}bool operator ==(const Data& r)const//设计data结构体的==操作{return (w == r.w) && (v == r.v);}};int head[N + 2];//标记每一个i的表的首元素,相当于将一维数组转换为二维数组Data goods[N], table[M];//goods[]存储物品信息,table[i]存储对应装前i个物品对应的(w,v)stack<int> numlist;//存放最终放入物品序号的栈int n, c;//物品数量和背包总容量// trace back to find the solution vector x[1……n]void traceBack(Data eState){//eState是最后一个i的表的最后一个数据信息int i, j;bool x[N + 2];for (i = n; i >= 1; --i){x[i] = false;for (j = head[i] - 1; j >= head[i - 1]; --j)//从p[i-1]的末尾遍历到p[i-1]的开头{if (table[j] + goods[i] == eState && (table[j].w != 0 || !j)){//这里判断有没有加入第i个物品,若加入,则将i序号进栈,并且将对应i-1的表的最好的数据赋值给estate进行回溯numlist.push(i);//cout << i << ",";//测试进栈情况eState = table[j];break;}}}}// jump points' method to slove the 0-1 bag's problemint GKnapSack(){int i, k, j, boundaryL, boundaryR, next;//boundaryL, boundaryR作为指针,卡在p[i-1]的左右为边界,next是p[i]要填写的位置,初始时next为//p[i]的首位置,k依次往后移动,直到到达p[i-1]的右边界Data temp;head[0] = 0;//p[0]的首位置为索引0table[0] = Data(0, 0);//没有装物品时各项数据都为0boundaryL = boundaryR = 0;next = 1;//p[1]要填写的位置即索引1head[1] = 1;//p[i]的首位置为1for (i = 1; i <= n; ++i){k = boundaryL;//数字k在处理中从p[i-1]的左边界移动到右边界for (j = boundaryL; j <= boundaryR; ++j){if (table[j].w + goods[i].w > c)break;/*先在 p(i-1)的元素 j 上得到一个新状态,然后 w 小于它的不受影响,直接搬*/temp = table[j] + goods[i];//将p[i-1]对应的列表中的移动到的数据的容量和价值分别加上第i件物品的容量和价值while (k <= boundaryR && table[k].w<temp.w)  {//next是p[i]要填写的位置,初始时next为p[i]的首位置,依次往后移动,//直到到达p[i-1]的右边界table[next] = table[k];++next;++k;}/*w 等于它的,对 v 取更大的值*/if (k <= boundaryR && table[k].w == temp.w){temp.v = max(temp.v, table[k].v);//如果容量相同,则取价值最大的++k;}/*w 大于它的,根据 v 值直接pass 掉 不合法的点(w 大但 v 小于前边的)*/  //这里pass的为q队列不合适的对if (temp.v > table[next - 1].v){table[next] = temp;++next;}while (k <= boundaryR && table[k].v <= table[next - 1].v)++k;                                                       //将多余的删除掉。这里忽略在p行的违规的对}while (k <= boundaryR){table[next] = table[k];++next;++k;}boundaryL = boundaryR + 1;//boundaryL指向p[i]的左边界,即下一个i对应的表的左边界,因为此时p[i]的表已经填好,要利用i标记来借助p[i]导出p[i+1]boundaryR = next - 1;//因为next指向p[i+1]的首位置的索引,所以boundaryR指向next-1,即得到p[i]的右边界head[i + 1] = next;}traceBack(table[next - 1]);return table[next - 1].v;}

算法复杂度分析?:
此算法的计算量在于求解p[i]
p[i]的跳跃点对应x1,...,xix_1,...,x_ix1​,...,xi​的0-1赋值,p[i]的跳跃点个数不超过2i2^i2i故计算时间为
O(∑i=1n2n=O(2n)O(\sum^n_{i=1}{2^n}=O(2^n)O(∑i=1n​2n=O(2n)
当所给的物品重量为整数时,∣p[i]∣<=c+1|p[i]|<=c+1∣p[i]∣<=c+1,所以总的时间复杂度为O(min(nc,2n))O(min(nc,2^n))O(min(nc,2n))

动态规划01背包问题之跳跃点解法相关推荐

  1. 动态规划—01背包问题

    原文作者:弗兰克的猫 原文地址:[动态规划]01背包问题 摘要: 01背包问题:n个物品放入容量为c的背包中. 常见解法: 分治法:递归计算,且存在重复计算的bug 自上而下填表法:从大到小使用递归计 ...

  2. 动态规划——01背包问题 看此一篇文章就够了

    本文讲述经典算法--动态规划的 常见问题 01背包  一篇文章带你学会01背包问题,妈妈再也不担心我遇到01背包了!!! 问题描述 有n个物品,它们有各自的体积和价值,现有给定容量m的背包,如何让背包 ...

  3. 动态规划---01背包问题(2种方法)

    一.动态规划 代表一类问题(最优子结构或子问题最优性)的一般解法,是设计方法或者策略,不是具体算法 本质:递推,核心是找到状态转移的方式,写出dp方程. 解决问题:交叉,重叠子问题(最优子问题) 形式 ...

  4. Leetcode动态规划——01背包问题

    内容参考 https://blog.csdn.net/yoer77/article/details/70943462 https://labuladong.github.io/ebook/动态规划系列 ...

  5. 动态规划——0-1背包问题

    文章出处:极客时间<数据结构和算法之美>-作者:王争.该系列文章是本人的学习笔记. 1 0-1背包问题 背包能够承受的总重量一定w,每个物品的总量不同int[] weight表示.怎么放才 ...

  6. 动态规划01背包问题入门学习,详细笔记,推荐阅读

    问题描述: 给定N种物品和一个背包.物品i的重量是Wi,其价值位Vi ,背包的容量为C.问应该如何选择装入背包的物品,使得转入背包的物品的总价值为最大?? 在选择物品的时候,对每种物品i只有两种选择, ...

  7. python实现动态规划0-1背包问题

    一.动态规划算法介绍 动态规划算法通常用于求解具有某种最优性质的问题.在这类问题中,可能会有许多可行解.每一个解都对应于一个值,我们希望找到具有最优值的解.动态规划算法与分治法类似,其基本思想也是将待 ...

  8. 详解动态规划01背包问题--JavaScript实现

    对其他动态规划问题感兴趣的,也可以查看 详解动态规划最少硬币找零问题--JavaScript实现 详解动态规划最长公共子序列--JavaScript实现 一开始在接触动态规划的时候,可能会云里雾里,似 ...

  9. 动态规划--01背包问题详解

    代码随想录day42和day43 动态规划 模块01背包问题 "即使到不了远方,心中也要有远方的模样." 文章目录 1. 01背包理论基础 1.1什么是背包问题 1.2二维dp数组 ...

最新文章

  1. 面试官:你说熟悉MySQL事务,那来谈谈事务的实现原理吧!
  2. 关于openGL学习心得
  3. sudo: pip:找不到命令
  4. 计算机应用基础 东师 离线,东师1609计算机应用基础离线作业(8页)-原创力文档...
  5. nginx 与php版本,nginx-php不同版本问题
  6. 【Linux】完美解决 nginx 的权限问题( Permission denied)
  7. Jquery遮罩插件,想罩哪就罩哪!
  8. OpenCV 图像金字塔buildPyramid、pyrDown、pyrUp
  9. 截获webView点击事件
  10. oracle数据从一个表空间导入到另外一个表空间
  11. 163editor 网页编辑器 获值
  12. SQL优化工具SQLAdvisor使用
  13. 3D优化之ShadowGun系列三:shader系列汇总
  14. 文件后缀和相应的文件类型,打开方法参考大全
  15. uni-app上传附件与附件预览
  16. startup_stm32xxxx.s文件问题
  17. 继承父类求解矩形,圆形的面积和周长
  18. 明星热图|小S代言新品牌;黄景瑜、高圆圆、木村光希及贾樟柯拍摄品牌广告;欧阳娜娜等出席品牌活动...
  19. IP数据包在网络中的传输过程
  20. poi 启用保护后取消_关于POI锁定保护Excel表格后的操作

热门文章

  1. 日迹2022.3.22
  2. 乌合之众 -- 群体心理
  3. java中jgit中checkout_JGit 切换分支
  4. CEF实现F5刷新快捷键
  5. 交换机S5720外网断开两次(12月1日,11月27日),关闭auto-port-defend功能,仅开启auto-defend。针对信任的IP,acl放通,然后在策略里面调用ACL
  6. C语言编写字符串连接函数
  7. 快递行业开启春节运营模式 多公司承诺“不打烊”
  8. javadoc 抽出代码中的注释
  9. openjudge 1.13.11 回文素数
  10. 不动的大图书馆 第一期