题目:

01背包问题描述:有编号分别为a,b,c,d,e的N=5件物品,它们的重量w分别是2,2,6,5,4,它们的价值v分别是6,3,5,4,6,每件物品数量只有一个,现在给你个承重为M=10的背包,如何让背包里装入的物品具有最大的价值总和sum_v?

在DP(dynamic programming,动态规划)问题中,01背包问题是比较基础和简单的了,但是网上很多人的讲解要么长长一大段,长篇公式理论,要么就是知识把状态转移方程列了出来,而没有说明为什么方程是这么写的,下面我力图将01背包问题中最简单最核心的概念和思路讲一下

1. 此01背包问题本质上是穷举背包容量和可供选择的物品(意思是里面的物品可能会放进背包,可能不会放进背包),取得最优解,只不过在穷举的过程中,会根据状态转移方程,只计算可能获得的最优解的部分,不去计算不是最优解的部分。具体来看,解题思路是把该问题分解为一个一个的小问题,一步步的通过小问题的最优解,最终得到大问题的最优解,跟我们人脑解题的思路是一样的。比如第一个小问题是“当我的背包承重M=1,只有编号为a的物品可供选择时,最优解是什么”,然后下一个小问题是建立在前一个小问题的基础上“当我的背包承重M=1,有编号为a,b的物品可供选择时,最优解是什么”,以此类推。

2. 为什么能列出状态转移方程?是因为每个状态的最优解,都是根据之前的状态的最优解获得的。具体到背包问题,有以下几点:

  a) 当物品备选情况(物品备选情况指:可供选择的物品的集合)一致时,背包容量M越大,那么sum_v一定大于等于原来的值。

  b) 背包容量M确定时,可供选择的物品N越多,那么sum_v一定大于等于原来的值。

  c) 由a)和b)可得,sum_v的最大值就是当M和N取到最大值时的sum_v

  c) 从思路上说,01背包问题有两个维度:背包容量M,和供选择物品数N。编程的本质是实现人类解决现实问题的思路。仔细想想,如果不借助计算机,你该如何解决这个问题?答案是,例如考虑M=1时,先考虑a能否放入背包,取得最大值,再考虑a和b能否放入背包(a和b都是备选,最终放入背包的可能是a,可能是b,也可能是ab),这时因此与之前只考虑a的情况相比,多了一个b,所以:

  • 要先判断b能否单独放进背包:

    • 如果不能,那么备选为a,b时最大值,等于备选只有a时的最大值(因为b是放不进背包的)。
    •   如果能,即b能够放进去,还有两种可能(即将b放进背包,和不将b放进背包),对这两种可能性,要取最大值:
      •   最终将b放进去(注:此时物品a是否被放进背包是未知的,原因是:剩余的背包容量可能不足以放进物品a,即要在剩余可选物品里找出最优解。
      •   最终没有将b放进去(因为后面可能有比b更合适的物品放进去),此时最大值等于备选只有a时的最大值

  用数学的方式描述上段话:sum_v[i][j]表示将前i件物品列为备选,背包容量为j时,能获得的最大价值;w[i]表示第i件物品的重量,v[i]表示第i件物品的价值

if 1 >=w[2]:sum_v[2][1] = max(sum_v[1][j-w[2]] + v[2], sum_v[1][1])
else:sum_v[2][1] = sum_v[1][1]

  推广到任意情况,即得到我们的状态转移方程

if j >=w[i]:sum_v[i][j] = max(sum_v[i-1][j-w[i]] + v[i], sum_v[i-1][j])
else:sum_v[i][j] = sum_v[i-1][j]

  sum_v的最大值就是sum_v[i][j]的最后一个元素

3. 计算时进行简单的数据结构改造。因为当i=1时,即计算开始阶段,还要考虑到如果第1件物品放不进去的情况,此时没有物品在背包中,因此重量和价值都是0.因此需要在表示物品重量和价值的列表前加一个数据0。

另外,当没有物品在背包中时,价值为0.所以需要sum_v[i][j]初始值全部设为0.

下面是详细代码:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import copyclass ZOPACK(object):def __init__(self,n,m,w,v):self.num = nself.capacity = mself.weight_list = [0,] + wself.value_list = [0,] + vself.Sum_Value_Metrix = self.__CreateMetrix__(self.num+1,self.capacity+1,0)def __CreateMetrix__(self,x,y,init_value):d2_list = []for i in range(x):d1_list = []for j in range(y):d1_list.append(init_value)d2_list.append(d1_list)return d2_listdef dp(self):sum_v = self.Sum_Value_Metrixnum = self.numcapacity = self.capacityw = self.weight_listv = self.value_listfor i in range(1,num+1):for j in range(1,capacity+1):if j >=w[i]:#print("i,j:%s,%s" % (i,j))sum_v[i][j] = max(sum_v[i-1][j-w[i]] + v[i], sum_v[i-1][j])else:sum_v[i][j] = sum_v[i-1][j]print("The max value we can get is: ", sum_v[-1][-1])print(sum_v)if __name__ == "__main__":num = 5capacity = 10weight_list = [2, 2, 6, 5, 4]value_list = [6, 3, 5, 4, 6]q = ZOPACK(num,capacity,weight_list,value_list)q.dp()

转载于:https://www.cnblogs.com/ArsenalfanInECNU/p/8945548.html

最清楚的01背包问题讲解相关推荐

  1. 动态规划之01背包问题讲解

    给大家附上一个题目吧,便于理解 ctest有n个苹果,要将它放入容量为v的背包.给出第i个苹果的大小和价钱,求出能放入背包的苹果的总价钱最大值. 输入:每组测试数据第一行为2个正整数,分别代表苹果的个 ...

  2. 0-1背包问题的简单解释

    01背包问题,是用来介绍动态规划算法最经典的例子,网上关于01背包问题的讲解也很多,我写这篇文章力争做到用最简单的方式,最少的公式把01背包问题讲解透彻. 01背包的状态转换方程 f[i,j] = M ...

  3. 题目1025:最大报销额(动态规划之01背包问题)

    题目1025:最大报销额 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5270 解决:1272 题目描述: 现有一笔经费可以报销一定额度的发票.允许报销的发票类型包括买图书(A类).文具 ...

  4. 【动态规划】01背包问题(通俗易懂,超基础讲解)

    问题描述 有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和? 为方便讲解和理解,下面讲述的例子均先用具体的数字代入,即:eg:number=4,capa ...

  5. 动态规划专题 01背包问题详解【转】

    对于动态规划,每个刚接触的人都需要一段时间来理解,特别是第一次接触的时候总是想不通为什么这种方法可行,这篇文章就是为了帮助大家理解动态规划,并通过讲解基本的01背包问题来引导读者如何去思考动态规划.本 ...

  6. 分支界限算法【0-1背包问题】按照优先队列式(LC)分支限界法求解0-1背包问题, 并给出限界函数,并画出该实例的状态空间树。

    目   录 回溯算法[0-1背包问题] 分支界限算法[0-1背包问题] 作业题(期末考试必考) 小结 回溯算法[0-1背包问题] 分支界限算法[0-1背包问题] 解决思路:采用优先队列式分支限界 Ø ...

  7. P01:01背包问题(转)

    题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. 基本思路 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. ...

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

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

  9. 0-1背包问题(多解)

    0-1背包问题(多解) 问题 有n个物品,它们有各自的体积和价值,现有给定容量c的背包,如何让背包里装入的物品具有最大的价值总和? 贪心(错解) 贪心策略有三种,分别为价值贪心(优先选取价值最大的), ...

  10. 【转】01背包问题动态规划详解

    转载自 sunstar1989 最终编辑 中华复生母 动态规划是用空间换时间的一种方法的抽象.其关键是发现子问题和记录其结果.然后利用这些结果减轻运算量. 比如01背包问题. 因为背包最大容量M未知. ...

最新文章

  1. Web.Config文件配置之连接默认错误页
  2. 搭建rtx服务并客户端登录
  3. OpenMV中AprilTag识别Python程序源码
  4. win10如何修改文件拓展名?
  5. MySQL 也替换了master、slave
  6. SFTP是什么?与FTP之间有什么区别
  7. cocoscreator editbox 只允许数字_《Cocos Creator游戏实战》做一个数字调节框
  8. 有关findviewbyid 一个错误用法
  9. HADOOP:Current usage: 399.9 MB of 1 GB physical memory used; 2.5 GB of 2.1 GB virtual memory used.
  10. Bailian2820 Ancient Cryptogram【密码】
  11. 【BZOJ】4668 冷战
  12. Benchmark Factory 使用 简介
  13. MySQL慢SQL探究
  14. mysql 库损坏恢复数据方法
  15. python笔记-2020/09/03下午-字符串练习(5)
  16. 虚拟养老院如何运作?虚拟养老院不提供床位-新导智能
  17. SAT语法之指示代词知识点
  18. C++Qt开发-string 与 QString 的相互转换
  19. KTV「消亡史」:辉煌、挫折与新生
  20. R语言计算玉米测交试验的配合力

热门文章

  1. 带宽和最高速率之间的换算
  2. Visual Paradigm 教程[UML]:如何在UML中绘制组件图?
  3. 大话css预编译处理(一)通读介绍篇
  4. SourceTree Win10 安装不成功解决过程记录
  5. 网络热词下的民意传播
  6. 免费的用户界面设计工具、工具包和资源备忘
  7. MySql基本的语法(学习笔记)
  8. 《电路分析导论(原书第12版)》一3.14 压控电阻
  9. gulp错误GulpUglifyError: unable to minify JavaScript解决
  10. linux下的raid及mdadm的命令详解