动态规划之01背包问题(最易理解的讲解)[通俗易懂]

动态规划之01背包问题(最易理解的讲解)[通俗易懂]01背包问题,是用来介绍动态规划算法最经典的例子,网上关于01背包问题的讲解也很多,我写这篇文章力争做到用最简单的方式,最少的公式把01背包问题讲解透彻。01背包的状态转换方程 f[i,j]=Max{f[i-1,j-Wi]+Pi(j>=Wi), f[i-1,j]}f[i,j]表示在前i件物品中选择若干件放在承重为j的背包中,可以取得的最大价值。Pi表示第i件物

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

01背包问题,是用来介绍动态规划算法最经典的例子,网上关于01背包问题的讲解也很多,我写这篇文章力争做到用最简单的方式,最少的公式把01背包问题讲解透彻。

01背包的状态转换方程 f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ),  f[i-1,j] }

f[i,j]表示在前i件物品中选择若干件放在承重为 j 的背包中,可以取得的最大价值。

Pi表示第i件物品的价值。

决策:为了背包中物品总价值最大化,第 i件物品应该放入背包中吗 ?


题目描述:

假设山洞里共有a,b,c,d ,e这5件宝物(不是5种宝物),它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包, 怎么装背包,可以才能带走最多的财富。

有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?

name weight value 1 2 3 4 5 6 7 8 9 10
a 2 6 0 6 6 9 9 12 12 15 15 15
b 2 3 0 3 3 6 6 9 9 9 10 11
c 6 5 0 0 0 6 6 6 6 6 10 11
d 5 4 0 0 0 6 6 6 6 6 10 10
e 4 6 0 0 0 6 6 6 6 6 6 6

只要你能通过找规律手工填写出上面这张表就算理解了01背包的动态规划算法。

首先要明确这张表是至底向上,从左到右生成的。

为了叙述方便,用e2单元格表示e行2列的单元格,这个单元格的意义是用来表示只有物品e时,有个承重为2的背包,那么这个背包的最大价值是0,因为e物品的重量是4,背包装不了。

对于d2单元格,表示只有物品e,d时,承重为2的背包,所能装入的最大价值,仍然是0,因为物品e,d都不是这个背包能装的。

同理,c2=0,b2=3,a2=6。

对于承重为8的背包,a8=15,是怎么得出的呢?

根据01背包的状态转换方程,需要考察两个值,

一个是f[i-1,j],对于这个例子来说就是b8的值9,另一个是f[i-1,j-Wi]+Pi;

在这里,

 f[i-1,j]表示我有一个承重为8的背包,当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值

f[i-1,j-Wi]表示我有一个承重为6的背包(等于当前背包承重减去物品a的重量),当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值

f[i-1,j-Wi]就是指单元格b6,值为9,Pi指的是a物品的价值,即6

由于f[i-1,j-Wi]+Pi = 9 + 6 = 15 大于f[i-1,j] = 9,所以物品a应该放入承重为8的背包

以下是actionscript3 的代码

		public function get01PackageAnswer(bagItems:Array,bagSize:int):Array
		{
			var bagMatrix:Array=[];
			var i:int;
			var item:PackageItem;
			for(i=0;i<bagItems.length;i++)
			{
				bagMatrix[i] = [0];
			}
			for(i=1;i<=bagSize;i++)
			{
				for(var j:int=0;j<bagItems.length;j++)
				{
					item = bagItems[j] as PackageItem;
					if(item.weight > i)
					{
						//i背包转不下item
						if(j==0)
						{
							bagMatrix[j][i] = 0;
						}
						else
						{
							bagMatrix[j][i]=bagMatrix[j-1][i];
						}
					}
					else
					{
						//将item装入背包后的价值总和
						var itemInBag:int;
						if(j==0)
						{
							bagMatrix[j][i] = item.value;
							continue;
						}
						else
						{
							itemInBag = bagMatrix[j-1][i-item.weight]+item.value;
						}
						bagMatrix[j][i] = (bagMatrix[j-1][i] > itemInBag ? bagMatrix[j-1][i] : itemInBag)
					}
				}
			}
			//find answer
			var answers:Array=[];
			var curSize:int = bagSize;
			for(i=bagItems.length-1;i>=0;i--)
			{
				item = bagItems[i] as PackageItem;
				if(curSize==0)
				{
					break;
				}
				if(i==0 && curSize > 0)
				{
					answers.push(item.name);
					break;
				}
				if(bagMatrix[i][curSize]-bagMatrix[i-1][curSize-item.weight]==item.value)
				{
					answers.push(item.name);
					curSize -= item.weight;
				}
			}
			return answers;
		}

PackageItem类

	public class PackageItem
	{
		public var name:String;
		public var weight:int;
		public var value:int;
		public function PackageItem(name:String,weight:int,value:int)
		{
			this.name = name;
			this.weight = weight;
			this.value = value;
		}
	}

测试代码

				var nameArr:Array=['a','b','c','d','e'];
				var weightArr:Array=[2,2,6,5,4];
				var valueArr:Array=[6,3,5,4,6];
				var bagItems:Array=[];
				for(var i:int=0;i<nameArr.length;i++)
				{
					var bagItem:PackageItem = new PackageItem(nameArr[i],weightArr[i],valueArr[i]);
					bagItems[i]=bagItem;
				}
				var arr:Array = ac.get01PackageAnswer(bagItems,10);

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/164395.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SVM——支持向量回归(SVR)[通俗易懂]

    SVM——支持向量回归(SVR)[通俗易懂]1、支持向量回归的原始问题先来看看SVM线性支持向量机(软间隔)的原始问题:其中ξi是松弛变量,但它实际上是hinge(合页)损失函数,所以ξi也作为对应的点(xi,yi)的损失,如下图所示:当点(xi,yi)位于间隔面上或者间隔面之外(这两种都是正确分类的情况)则ξi=0,若点(xi,yi)位于分割面上或者正确分类且位于间隔面之内或者位于分错的那一侧,这三种情况都是有损失的,损失…

    2022年5月20日
    32
  • YGC和FGC是什么「建议收藏」

    YGC和FGC是什么「建议收藏」1.YGC和FGC是什么YGC:对新生代堆进行gc。频率比较高,因为大部分对象的存活寿命较短,在新生代里被回收。性能耗费较小。FGC:全堆范围的gc。默认堆空间使用到达80%(可调整)的时候会触发fgc。以我们生产环境为例,一般比较少会触发fgc,有时10天或一周左右会有一次。2.什么时候执行YGC和FGCedn空间不足,执行younggcb.old空间不足,…

    2022年6月19日
    48
  • mysql临时表更新_MySql 临时表

    mysql临时表更新_MySql 临时表今天在项目中遇到一个 当 mysql 的 in 语句中数据量很大时 建立一个临时表的例子 于是楼主整理了一下关于临时表的知识 与大家分享一下 首先 临时表只在当前连接可见 当关闭连接时 Mysql 会自动删除表并释放所有空间 因此在不同的连接中可以创建同名的临时表 并且操作属于本连接的临时表 建立临时表 CREATETEMPOR table idVARCHAR 32 N

    2025年10月6日
    3
  • 教程-经典Delphi教程网

    教程-经典Delphi教程网有理想+志同道合的人+取长补短去协同工作=完美团队一流的项目+三流的执行者=垃圾项目三流的项目+一流的执行者=完美项目自己公司网址:http://www.kaideruixin.icoc.cc/电脑管家误报提交地址:http://bbs.guanjia.qq.com/forum.php?mod=forumdisplay&fid=63本本驱动网站:http://www….

    2022年6月26日
    25
  • linux未找到 ftp命令,Linux服务器ftp命令找不到「建议收藏」

    linux未找到 ftp命令,Linux服务器ftp命令找不到「建议收藏」ftpcommondnotfind先用命令rpm-qvsftpd检查是否安装了ftp服务器若显示vsftpd-2.2.2-11.el6_4.1.x86_64这样的信息,说明FTP服务器已安装,那为什么FTP命令不能用呢,那是FTP客户端没安装的缘故。下载ftp-0.17-51.1.el6.x86_64.rpm,下载地址有:http://rpm.pbone.net/index.php3/s…

    2025年11月28日
    8
  • Mac OS 下三种修改Hosts文件的方法[通俗易懂]

    Mac OS 下三种修改Hosts文件的方法

    2022年2月11日
    54

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号