数学建模背包问题
利用动态规划解决01背包问题01背包问题动态规划

利用动态规划解决01背包问题01背包问题动态规划背包问题是一个经典的动态规划模型,很多关于算法的教材都把它作为一道例题,该问题既简单又容易理解,而且在某种程度上还能够揭示动态规划的本质。
将具有不同重量和价值的物体装入一个有固定载重量的背包,以获取最大价值,这类问题被称为背包问题。
背包问题可以扩展出很多种问题,而01背包问题是最常见、最有代表性的背包问题。
一、问题描述给定一个载重量为M的背包及n个物体,物体i的重量为wi、价值为pi,1≤i≤n,要求把这些物体装入背包,使背包内的物体价值总量最大。
此处我们讨论的物体是不可分割的,通常称这种物体不可分割的背包问题为01背包问题。
二、基本思路01背包问题的特点是:每种物体只有一件,可以选择放或者不放。
假设:xi表示物体i被装入背包的情况,xi=0,1。
当xi=0时,表示物体没有被装入背包;当xi=1时,表示物体被装入背包。
根据问题的要求,有如下的约束方程(1)和目标函数(2):三、利用动态规划法求解01背包问题(一)动态规划算法的基本思想动态规划算法通常用于求解具有某种最优性质的问题。
在这类问题中,可能会有许多可行解。
每一个解都对应于一个值,我们希望找到具有最优值的解。
动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。
若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算很多次。
如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。
我们可以用一个表来记录所有已解的子问题的答案。
不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中,这就是动态规划法的基本思路。
具体的动态规划算法多种多样,但它们具有相同的填表格式。
(二)算法设计假定背包的载重量范围为0~m。
背包问题四种不同算法的实现

交通大学数理与软件工程学院题目0-1背包问题算法实现院系数理院专业班级信计09学生雷雪艳学号202105130指导教师二O一二年六月五日一、问题描述:1、0—1背包问题:给定n 种物品和一个背包,背包最大容量为M ,物品i 的重量是w i ,其价值是平P i ,问应当如何选择装入背包的物品,似的装入背包的物品的总价值最大? 背包问题的数学描述如下:2、要求找到一个n 元向量(x1,x2…xn),在满足约束条件:⎪⎩⎪⎨⎧≤≤≤∑10i i i x M w x 情况下,使得目标函数px ii ∑max ,其中,1≤i ≤n ;M>0;wi>0;pi>0。
满足约束条件的任何向量都是一个可行解,而使得目标函数到达最大的那个可行解那么为最优解[1]。
给定n 种物品和1个背包。
物品i 的重量是wi ,其价值为pi ,背包的容量为M 。
问应如何装入背包中的物品,使得装人背包中物品的总价值最大?在选择装人背包的物品时,对每种物品i 只有两种选择,即装入背包、不装入背包。
不能将物品i 装人背包屡次,也不能只装入局部的物品i 。
该问题称为0-1背包问题。
0-1背包问题的符号化表示是,给定M>0, w i >0, pi >0,1≤i ≤n ,要求找到一个n 元0-1向量向量(x1,x2…xn), X i =0 或1 , 1≤i ≤n, 使得Mwx ii≤∑ ,而且px ii∑到达最大[2]。
二、解决方案:方案一:贪心算法1、贪心算法的根本原理与分析贪心算法总是作出在当前看来是最好的选择,即贪心算法并不从整体最优解上加以考虑,它所作出的选择只是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,但对围相当广的许多问题它能产生整体最优解。
在一些情况下,即使贪心算法不能得到整体最优解,但其最终结果却是最优解的很好近似解。
贪心算法求解的问题一般具有两个重要性质:贪心选择性质和最优子构造性质。
背包问题

完全背包问题也是一个相当基础的背包问题,它有两个状态转移方程,分别在“基本思路”以及“O(VN) 的算法“的小节中给出。希望你能够对这两个状态转移方程都仔细地体会,不仅记住,也要弄明白它们是怎么得 出来的,最好能够自己想一种得到这些方程的方法。事实上,对每一道动态规划题目都思考其方程的意义以及如 何得来,是加深对动态规划的理解、提高动态规划功力的好方法。
这个问题非常类似于01背包问题,所不同的是每种物品有无限件。也就是从每种物品的角度考虑,与它相关 的策略已并非取或不取两种,而是有取0件、取1件、取2件……等很多种。如果仍然按照解01背包时的思路,令 f[i,v]表示前i种物品恰放入一个容量为v的背包的最大权值。仍然可以按照每种物品不同的策略写出状态转移方程, 像这样:f[i,v]=max{f[i,v-vi]+wi,f[i-1,v]}。这跟01背包问题一样有O(N*V)个状态需要求解,但求解每个状态的 时间则不是常数了,求解状态f[v]的时间是O(v/c),总的复杂度是超过O(VN)的。
背包问题已经研究了一个多世纪,早期的作品可追溯到1897年 数学家托比亚斯·丹齐格(Tobias Dantzig, 1884-1956)的早期作品 ,并指的是包装你最有价值或有用的物品而不会超载你的行李的常见问题。
应用
1998年的石溪布鲁克大学算法库的研究表明,在75个算法问题中,背包问题是第18个最受欢迎,第4个最需 要解决的问题(前三为后kd树,后缀树和bin包装问题)。
基础背包
题目 基本思路
空间复杂 示例程序
递归实现 程序
测试数据 总结
有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些 物品的重量总和不超过背包容量,且价值总和最大。
背包问题--CH

想必大家看出了和01背包的区别,这里 的内循环是顺序的,而01背包是逆序的。 现在关键的是考虑:为何完全背包可以这 么写? 在次我们先来回忆下,01背包逆序的原因? 是为了是max中的两项是前一状态值,这就 对了。 那么这里,我们顺序写,这里的max中的两 项当然就是当前状态的值了,为何?
因为每种背包都是无限的。当我们把i从1到N循 环时,f[v]表示容量为v在前i种背包时所得的价 值,这里我们要添加的不是前一个背包,而是 当前背包。所以我们要考虑的当然是当前状态。
初始化
题目的两种问法: 1):求“恰好装满背包”时的最优解
dp[0] = 0 ; for(int i = 1; i <= n; ++i) dp[i] = -INF ;
2):没有要求必须把背包装满 for(int i = 1; i <= n; ++i) dp[i] = 0 ;
POJ 3624 #include <cstdio>
for(i = 1; i<= n; ++i)
dp[0][i] = 0 ;
练习:poj 3624
该算法存在的问题
那个状态转移方程中的dp[][]是一个二维的数组, 在我们写程序的时候,内存往往有限制,当dp[][] 的每一维都开到10000以上是,程序是不能够 运行的。 优化空间复杂度: 根据状态转移方程dp[i][v] = max(dp[i-1][v], dp[i-1][v-c[i]]+w[i])知: dp[i][v]只与其前一个状态有关。
案例一(简单背包问题)
•这N个物品在装入的过程中是可分的 •解决方案(贪心法): •选择单位重量收益最大的物品装入背包, 即按wi/ci的非曾次序选取物品。 例:设有载重M=20的背包,3件物品的重量 为(c0, c1, c2)=(18, 15, 10),物品装入背包的收 益为(w0, w1, w2)=(25, 24, 15)。
背包问题九讲

背包问题九讲目录P01: 01背包问题题目有N件物品和一个容量为V的背包。
第i件物品的费用是c[i],价值是w[i]。
求解将哪些物品装入背包可使价值总和最大。
基本思路这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。
用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。
则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。
所以有必要将它详细解释一下:将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。
如果不放第i件物品,那么问题就转化为前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题就转化为前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。
优化空间复杂度以上方法的时间和空间复杂度均为O(VN),其中时间复杂度应该已经不能再优化了,但空间复杂度却可以优化到O。
先考虑上面讲的基本思路如何实现,肯定是有一个主循环i=1..N,每次算出来二维数组f[i][O..V]的所有值。
那么,如果只用一个数组f[0..V],能不能保证第i次循环结束后f[v]中表示的就是我们定义的状态f[i][v]呢?f[i][v]是由f[i-1][v]和f[i-1][v-c[i]]两个子问题递推而来,能否保证在推f[i][v]时(也即在第i次主循环中推f[v]时)能够得到f[i-1][v]和f[i-1][v-c[i]] 的值呢?事实上,这要求在每次主循环中我们以v=V..O的顺序推f[v],这样才能保证推f[v]时f[v-c[i]]保存的是状态f[i-1][v-c[i]]的值。
背包问题 动态规划

背包问题动态规划背包问题是一个经典的动态规划问题,主要是在给定的一些物品中选择一部分物品放入背包中,使得放入背包的物品总价值最大。
背包问题是动态规划中的一个重要问题,可以用来解决多种实际问题,比如旅行商问题、资源分配等。
在背包问题中,我们有一个容量为W的背包和n个物品,每个物品都有一个重量和一个价值。
我们需要选择一些物品放入背包中,使得放入背包的物品总重量不超过背包容量,并且总价值最大。
动态规划是一种算法解决问题的思想,其基本思路是将问题划分为重复的子问题,并利用子问题的解来构建原问题的解。
在背包问题中,动态规划可以分为以下几步:1. 状态定义:定义一个二维数组dp[i][j],表示在前i个物品中,背包容量为j时的最大价值。
2. 状态转移方程:dp[i][j]的状态转移方程可以表示为:dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]),其中w[i]表示第i个物品的重量,v[i]表示第i个物品的价值。
3. 边界条件:当i=0时,dp[0][j] = 0,表示没有物品可选时的情况;当j=0时,dp[i][0] = 0,表示背包容量为0时,无论有多少物品可选,最大价值都为0。
4. 最优解求取:根据状态转移方程,我们可以通过填充dp数组来求取最优解。
在填充dp数组时,需要注意边界条件和状态转移方程的递推关系。
5. 回溯求解:通过填充dp数组,我们可以得到最大价值,但是无法得到具体的物品组合。
为了得到具体的物品组合,我们可以采用回溯的方法,从dp数组中找到最大价值的物品。
从最后一个物品开始,倒着依次回溯,如果dp[i][j] > dp[i-1][j],表示第i个物品被选中,否则不被选中。
通过以上步骤,我们可以解决背包问题,并得到最优解。
背包问题的动态规划算法时间复杂度为O(nW),其中n表示物品的个数,W表示背包的容量。
由于需要填充dp数组,所以需要额外的空间来存储dp数组,空间复杂度为O(nW)。
动态规划背包问题
P01: 01背包问题题目有N件物品和一个容量为V的背包。
第i件物品的费用是c[i],价值是w[i]。
求解将哪些物品装入背包可使价值总和最大。
基本思路这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。
用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。
则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。
所以有必要将它详细解释一下:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。
如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。
优化空间复杂度以上方法的时间和空间复杂度均为O(N*V),其中时间复杂度基本已经不能再优化了,但空间复杂度却可以优化到O(V)。
先考虑上面讲的基本思路如何实现,肯定是有一个主循环i=1..N,每次算出来二维数组f[i][0..V]的所有值。
那么,如果只用一个数组f[0..V],能不能保证第i次循环结束后f[v]中表示的就是我们定义的状态f[i][v]呢?f[i][v]是由f[i-1][v]和f[i-1][v-c[i]]两个子问题递推而来,能否保证在推f[i][v]时(也即在第i次主循环中推f[v]时)能够得到f[i-1][v]和f[i-1][v-c[i]]的值呢?事实上,这要求在每次主循环中我们以v=V..0的顺序推f[v],这样才能保证推f[v]时f[v-c[i]]保存的是状态f[i-1][v-c[i]]的值。
背包问题状态转移方程
背包问题状态转移方程1. 背包问题简介背包问题是一种经典的组合优化问题,它的目标是在给定的一组物品中选择一些物品放入背包中,使得物品的总价值最大,同时保证背包的总容量不超过限制。
背包问题可以分为0-1背包问题、完全背包问题和多重背包问题等不同类型,其中最常见的是0-1背包问题。
在0-1背包问题中,每个物品只能选择放入背包一次或不放入背包。
2. 0-1背包问题状态转移方程在0-1背包问题中,我们假设有N个物品,每个物品的重量分别为w1, w2, …, wn,价值分别为v1, v2, …, vn。
背包的总容量为C。
令dp[i][j]表示前i个物品中选择一些物品放入容量为j的背包中所能获得的最大价值。
对于第i个物品,有两种选择:放入背包或不放入背包。
如果选择放入背包,那么背包中的总重量就会增加wi,总价值就会增加vi。
此时,dp[i][j]的值就等于dp[i-1][j-wi]加上当前物品的价值vi。
如果选择不放入背包,那么dp[i][j]的值就等于dp[i-1][j],即前i-1个物品中选择一些物品放入容量为j的背包中所能获得的最大价值。
综上所述,0-1背包问题的状态转移方程可以表示为:dp[i][j] = max(dp[i-1][j], dp[i-1][j-wi] + vi)其中,1 <= i <= N,0 <= j <= C。
3. 0-1背包问题的求解0-1背包问题可以使用动态规划的方法进行求解。
首先,我们需要创建一个二维数组dp,其中dp[i][j]表示前i个物品中选择一些物品放入容量为j的背包中所能获得的最大价值。
然后,我们可以使用嵌套循环来遍历物品和背包容量,根据状态转移方程来计算dp[i][j]的值。
具体的求解过程如下:for i from 1 to N:for j from 0 to C:if j >= wi:dp[i][j] = max(dp[i-1][j], dp[i-1][j-wi] + vi)else:dp[i][j] = dp[i-1][j]最后,dp[N][C]就是问题的解,即前N个物品中选择一些物品放入容量为C的背包中所能获得的最大价值。
背包问题
(0-1)背包问题的解法小结1.动态规划法递推关系:– 考虑一个由前i 个物品(1≤i ≤n )定义的实例,物品的重量分别为w 1,…,w i ,价值分别为v 1,…,v i ,背包的承重量为j (1≤j ≤W )。
设V [I,j]为该实例的最优解的物品总价值– 分成两类子集:• 根据定义,在不包括第i 个物品的子集中,最优子集的价值是V [i -1,j ]• 在包括第i 个物品的子集中(因此,j -w ≥0),最优子集是由该物品和前i -1个物品中能够放进承重量为i -w j 的背包的最优子集组成。
这种最忧子集的总价值等于v i +V [i -1,j -w i ].0]0,[时,0 当0;][0,时,0初始条件:当],1[}],1[],,1[max{],[=≥=≥<≥⎩⎨⎧-+---=i V i j V j w j w j j i V v w j i V j i V j i V i i i i以记忆功能为基础的算法:用自顶向下的方式对给定的问题求解,另外维护一个类似自底向上动态规划算法使用的表格。
一开始的时候,用一种“null”符号创始化表中所有的单元,用来表明它们还没有被计算过。
然后,一旦需要计算一个新的值,该方法先检查表中相应的单元:如果该单元不是“null ”,它就简单地从表中取值;否则,就使用递归调用进行计算,然后把返回的结果记录在表中。
算法 MFKnapsack(I,j)//对背包问题实现记忆功能方法//输入:一个非负整数i 指出先考虑的物品数量,一个非负整数j 指出了背包的承重量 //输出:前i 个物品的最伏可行子集的价值//注意:我们把输入数组Weights[1..n],Values[1..n]和表格V[0..n,0..W]作为全局变量,除了行0和列0用0初始化以外,V 的所有单元都用-1做初始化。
if V[I,j]<01if j<Weights[i]value ←MFKnapsack(i-1,j)elsevalue ←max(MFKnapsack(i-1),j), Value[i]+MFKnapsack(i-1,j-eights[i]))V[I,j]←valuereturn V[I,j]2.贪心算法1) 背包问题基本步骤:首先计算每种物品单位重量的价值Vi/Wi ,然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。
0-1背包问题的近似算法
0-1背包问题的近似算法0-1背包问题的近似算法对问题特点和算法思想做一些整理如下:这类问题其实很有意思,做数学和做计算机的人都会研究,而且我这里将要提到的论文都是做计算机的人所写的。
问题简述0-1 Knapsack Problem (0-1背包问题,下面简称KP)和Subset Sum Problem (子集合加总问题,下面简称SSP)是经典的NP完全问题。
两个问题简要描述如下:KP:有n个物品要放入背包,第i个物品的价值为ci,占据体积为vi,背包的总容积为V,要选择一部分物品放入背包,使得他们的总价值最大。
对应的优化问题是maxxi∑ci∗xis.t.∑vi∗xi≤V,xi∈{0,1}这里xi代表是否选取第i个物品进背包,等于1就代表放入背包,等于0代表不放入背包。
SSP: 给一个集合{c1,c2,…,cn},还有一个目标值V,问能否选出一个子集,使得子集中元素求和刚好等于V。
我们一般考虑的是他的另一种表述方式:选出一个子集,使得子集中元素求和不超过V,且尽量大。
对应的优化问题是maxxi∑ci∗xis.t.∑ci∗xi≤V,xi∈{0,1}这里xi代表是否选入子集,等于1就是选入子集,等于0就是不选入子集。
SSP是KP的特殊情况,也即当ci=vi的时候,KP退化为SSP,从问题式子上看,也完全一样了。
尽管如此,研究了KP不代表就不用研究SSP了,后面会说明这一点。
精确算法与近似算法这两个问题都有很简单的动态规划算法可以精确求解,但可惜算法的时间复杂度是伪多项式的,也即和V相关,但V不是问题输入数据的规模,n才是。
在ACM竞赛等算法比赛中,经常会遇到一些问题属于KP的变种,而伪多项式算法也就足够了。
由于网上资料很多,而且难度不大,这里就不详细介绍了。
如果你不知道,请你搜索“动态规划求解0-1背包问题”。
这里我们更关心多项式近似算法,也即PTAS(Polynomial Time Approximation Scheme),也即对任意给定的ϵ,算法可以在关于n的多项式时间内求得一个解,且该解和真实最优解的最多相差ϵ倍。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
背包问题
背包问题(Knapsack problem)是一种组合优化的NP 完全问题。
问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。
问题的名称来源于如何选择最合适的物品放置于给定背包中。
相似问题经常出现在商业、组合数学,计算复杂性理论、密码学和应用数学等领域中。
也可以将背包问题描述为决定性问题,即在总重量不超过W 的前提下,总价值是否能达到V ?它是在1978年由Merkel 和Hellman 提出的
一、定义:
背包问题属于组合优化问题,一般的最优化问题由目标函数和约束条件两部部分组成:
我们有n 种物品,物品i 的重量为w i ,价格为p i 。
我们假定所有物品的重量和价格都是非负的。
背包所能承受的最大重量为W 。
如果限定每种物品只能选择0个或1个,则问题称为0-1背包问题。
可以用公式表示为:
1
max n
i i i p x =∑
1
..,n i i i S T w x W =≤∑ {}0,1i x ∈
如果限定物品i 最多只能选择b i 个,则问题称为有界背包问题。
可以用公式表示为:
1max n
i i i p x =∑
1..,n i i i S T w x
W =≤∑ {}0,1,,i i x b ∈⋅⋅⋅
如果不限定每种物品的数量,则问题称为无界背包问题。
各类复杂的背包问题总可以变换为简单的0-1背包问题进行求解。
二、基本模型的建立方法
1、0-1背包问题的数学模型(最基础的背包问题)
分类:0-1背包问题简单分为一维背包和二维背包问题。
特点:每种物品仅有一件,可以选择放或不放。
1.1 一维背包问题
问题:一个旅行者准备进行徒步旅行,为此他必须决定携带若干物品。
设有n 件物品可供他选择,编号为1,2,...,n 第i 件物品重量为i w 千克,价值为i p 元,他能携带的最大重量为w 千克。
他应该装入哪几件物品价值最大。
解:引入变量i x ,且设
1,(1,2,,)0,i i x i n i ⎧==⎨⎩表示将第种物品装入包中表示不将第种物品装入包
于是此问题的数学模型为:
1max n
i i i f p x ==∑
1122.....01,1,2,...,.n n i
w x w x w x W S T x i n +++≤⎧⎨==⎩或 1.2 二维背包问题
一维背包问题只考虑了背包重量的限制,如果再增加背包体积的限制为V ,并设第i 件物品的体积i v ,问如何携带可使总价值最大。
这就是二维背包问题。
它的数学模型为:
1max n
i i i f p x ==∑
11221122........01,1,2,...,.n n n n i
w x w x w x W S T v x v x v x V x i n +++≤⎧⎪+++≤⎨⎪==⎩或
2、有界背包的数学模型
特点:能够选择的物品数则可以在某个范围内取值。
物品j 最多可以选择j m 个,那么有界背包问题可以描述为:
1max n
i i i f p x ==∑
1..n
i i i S T w x C =≤∑ {}0,1,...,1,2,...,.i j x m j n ∈=
3、无界背包问题的数学模型
特点:无界背包问题实际上就是有界背包问题的扩展,每个物品可以任意的取。
但是因为背包的承重能力有限,每个物品的数目不可能取到无穷大,因此,实际上它仍是一个有界背包问题。
适用范围:
背包问题(Knapsack Problem )是组合优化领域内经典的NP 完备问题,是一个在运筹学领域常见的优化难题。
背包问题的研究起源于旅行者携带用品的背景,要求在旅行袋容积有一定限制的情况下,如何分配资源使得收益最大。
很多问题都可以建模为背包问题,如在管理中的资源分配、资金预算、投资决策、货物装载、项目选择,工厂里的下料问题等上都有着广泛的应用。
0-1背包源程序:
#include<iostream.h>
#define n 5
#define m 10
void knapbag(int *w,int *vl)
{
int c[n+1][m+1];//从1…i …item 物品中,背包剩余空间为0<=j<=max_wgt 的最大价值 for (int i=0;i<=n;i++)//初始化
{
for (int j=0;j<=m;j++)
{
c[i][j]=0;
}
}
//c(i,j)=max{c(i-1,j), c(i-1,j-w[i])+vl(i)}
for (i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
if (w[i]<=j)
{
if (vl[i]+c[i-1][j-w[i]]>c[i-1][j])
{
c[i][j]=vl[i]+c[i-1][j-w[i]];//选择第i物品
}
else
c[i][j]=c[i-1][j];//不选择第i个物品
}
else
c[i][j]=c[i-1][j];//剩余容量不够
}//endfor
}//endfor
cout<<"最优解:";
cout<<c[n][m]<<endl;//返回最大值
////算出是由哪几个物品组成
int temp_wei=m;
int x[n+1]={0,0,0,0};
for (i=n;i>0;i--)
{
if (c[i][temp_wei]==c[i-1][temp_wei])//最后一个肯定是最大价值的{
x[i]=0;
}
else
{
x[i]=1;
temp_wei-=w[i];
}
}
cout<<"应装入的物品有:";
for (i=0;i<=n;i++)
{
if (x[i])
{
cout<<"第"<<i<<"件\t";
}
}
cout<<endl;
}
int main()
{
int w[6]={0,2,2,6,5,4};//物品质量
int vl[6]={0,6,3,5,4,6};//物品价值
knapbag(w,vl);
return 0;
}。