01背包详解包含路径输出

合集下载

0-1背包问题详解二(完全背包问题)

0-1背包问题详解二(完全背包问题)

0-1背包问题详解⼆(完全背包问题)问题描述给定n种物品和⼀个背包。

物品i的重量是w(i),其价值为v(i),背包的容量为c(即最多能够装c重量的物品)。

这n种物品可以重复放置(这是与普通背包问题的不同之处)。

输⼊n=5,c=6.物品容量和价值分别为:2 62 36 55 44 6最后输出时:18问题求解:f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<=v}似乎利⽤上⾯那个公式就可以很好的求出解。

这⾥给出另外⼀组公式,该公式和上⽂的公式是⼀样的,只是第⼆个for语句的倒过来。

for i=1..Nfor v=0..Vf[v]=max{f[v],f[v-cost]+weight}为什么这样⼀改就可⾏呢?⾸先想想为什么上⽂中要按照v=V..0的逆序来循环。

这是因为要保证第i次循环中的状态f[i][v]是由状态f[i-1][v-c[i]]递推⽽来。

换句话说,这正是为了保证每件物品只选⼀次,保证在考虑“选⼊第i件物品”这件策略时,依据的是⼀个绝⽆已经选⼊第i件物品的⼦结果f[i-1][v-c[i]]。

⽽现在完全背包的特点恰是每种物品可选⽆限件,所以在考虑“加选⼀件第i种物品”这种策略时,却正需要⼀个可能已选⼊第i种物品的⼦结果f[i][vc[i]],所以就可以并且必须采⽤v=0..V的顺序循环。

这就是这个简单的程序为何成⽴的道理。

1void compelteKnapsack(){2int c,n;3 cout<<"请输⼊最⼤容量,⼩于100"<<endl;4 cin>>c;5 cout<<"请输⼊背包个数"<<endl;6 cin>>n;7 cout<<"请输⼊各个背包重量和价值"<<endl;8for(int i=1;i<=n;i++){9 cin>>w[i]>>v[i];10 }11for(int i=0;i<=n;i++)12 p[i]=0;13for(int i=1;i<=n;i++)14for(int j=w[i];j<=c;j++)15 p[j]=max(p[j],p[j-w[i]]+v[i]);16 cout<<"结果是"<<p[c]<<endl;17 }View Code版权所有,欢迎转载,但是转载请注明出处:。

分支界限方法01背包问题解题步骤

分支界限方法01背包问题解题步骤

分支界限方法是一种用于解决优化问题的算法。

在动态规划算法中,分支界限方法被广泛应用于解决01背包问题。

01背包问题是一个经典的动态规划问题,其解题步骤如下:1. 确定问题:首先需要明确01背包问题的具体描述,即给定一组物品和一个背包,每个物品有自己的价值和重量,要求在不超过背包容量的情况下,选取尽可能多的物品放入背包,使得背包中物品的总价值最大。

2. 列出状态转移方程:对于01背包问题,可以通过列出状态转移方程来描述问题的求解过程。

假设dp[i][j]表示在前i个物品中,背包容量为j时能够获得的最大价值,则状态转移方程可以表示为:dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]]+v[i])3. 初始化边界条件:在动态规划中,需要对状态转移方程进行初始化,一般情况下,dp数组的第一行和第一列需要单独处理。

对于01背包问题,可以初始化dp数组的第一行和第一列为0。

4. 利用分支界限方法优化:针对01背包问题,可以使用分支界限方法来优化动态规划算法的效率。

分支界限方法采用广度优先搜索的思想,在每一步选择最有希望的分支,从而减少搜索空间,提高算法的效率。

5. 实际解题步骤:根据上述步骤,实际解决01背包问题的步骤可以概括为:确定问题,列出状态转移方程,初始化边界条件,利用分支界限方法优化,最终得到问题的最优解。

分支界限方法在解决01背包问题时起到了重要的作用,通过合理的剪枝策略,可以有效地减少动态规划算法的时间复杂度,提高问题的求解效率。

分支界限方法也可以应用于其他优化问题的求解过程中,在算法设计和实现中具有重要的理论和实际意义。

在实际应用中,分支界限方法需要根据具体问题进行灵活选择和调整,结合动态规划和剪枝策略,以便更好地解决各类优化问题。

掌握分支界限方法对于解决复杂问题具有重要的意义,也是算法设计和优化的关键技术之一。

分支界限方法在解决01背包问题的过程中,具有重要的作用。

(完整版)01背包问题

(完整版)01背包问题

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

01背包的状态转换方程f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ), f[i-1,j] }只要你能通过找规律手工填写出上面这张表就算理解了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(varj:int=0;j<bagItems.length;j++){item = bagItems[j] as PackageItem;if(item.weight > i){//i背包转不下itemif(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 answervar 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();break;}if(bagMatrix[i][curSize]-bagMatrix[i-1][curSize-item.weight ]==item.value){answers.push();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){ = name;this.weight = weight;this.value = value;}}测试代码varnameArr: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(vari: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);。

蛮力法、动态规划法、回溯法和分支限界法求解01背包问题【精选】

蛮力法、动态规划法、回溯法和分支限界法求解01背包问题【精选】

一、实验内容:分别用蛮力法、动态规划法、回溯法和分支限界法求解0/1背包问题。

注:0/1背包问题:给定种物品和一个容量为的背包,物品的重n C i 量是,其价值为,背包问题是如何使选择装入背包内的物品,使得装i w i v 入背包中的物品的总价值最大。

其中,每种物品只有全部装入背包或不装入背包两种选择。

二、所用算法的基本思想及复杂度分析:1.蛮力法求解0/1背包问题:1)基本思想:对于有n 种可选物品的0/1背包问题,其解空间由长度为n 的0-1向量组成,可用子集数表示。

在搜索解空间树时,深度优先遍历,搜索每一个结点,无论是否可能产生最优解,都遍历至叶子结点,记录每次得到的装入总价值,然后记录遍历过的最大价值。

2)代码:#include<iostream>#include<algorithm>using namespace std;#define N 100//最多可能物体数struct goods //物品结构体{int sign;//物品序号int w;//物品重量int p;//物品价值}a[N];bool m(goods a,goods b){return (a.p/a.w)>(b.p/b.w);}int max(int a,int b){return a<b?b:a;}int n,C,bestP=0,cp=0,cw=0;int X[N],cx[N];/*蛮力法求解0/1背包问题*/int Force(int i){if(i>n-1){if(bestP<cp&&cw+a[i].w<=C){for (int k=0;k<n;k++)X[k]=cx[k];//存储最优路径bestP=cp;}return bestP;}cw=cw+a[i].w;cp=cp+a[i].p;cx[i]=1;//装入背包Force(i+1);cw=cw-a[i].w;cp=cp-a[i].p;cx[i]=0;//不装入背包Force(i+1);return bestP;}int KnapSack1(int n,goods a[],int C,int x[]){Force(0);return bestP;}int main(){goods b[N];printf("物品种数n: ");scanf("%d",&n);//输入物品种数printf("背包容量C: ");scanf("%d",&C);//输入背包容量for (int i=0;i<n;i++)//输入物品i 的重量w 及其价值v {printf("物品%d 的重量w[%d]及其价值v[%d]:",i+1,i+1,i+1);scanf("%d%d",&a[i].w,&a[i].p);b[i]=a[i];}int sum1=KnapSack1(n,a,C,X);//调用蛮力法求0/1背包问题printf("蛮力法求解0/1背包问题:\nX=[ ");for(i=0;i<n;i++)cout<<X[i]<<" ";//输出所求X[n]矩阵printf("]装入总价值%d\n",sum1);bestP=0,cp=0,cw=0;//恢复初始化}3)复杂度分析:蛮力法求解0/1背包问题的时间复杂度为:。

01背包详解包含路径输出

01背包详解包含路径输出

背包问题——“01背包”详解及实现(包含背包中具体物品的求解)分类:背包问题 2011-11-26 14:41 9554人阅读评论(10) 收藏举报pathtabledelete测试c算法-----Edit by ZhuSenlin HDU 01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为C1,C2,…,Cn,与之相对应的价值为W1,W2,…,Wn.求解将那些物品装入背包可使总价值最大。

动态规划(DP):1)子问题定义:F[i][j]表示前i件物品中选取若干件物品放入剩余空间为j的背包中所能得到的最大价值。

2)根据第i件物品放或不放进行决策(1-1)其中F[i-1][j]表示前i-1件物品中选取若干件物品放入剩余空间为j的背包中所能得到的最大价值;而F[i-1][j-C[i]]+W[i]表示前i-1件物品中选取若干件物品放入剩余空间为j-C[i]的背包中所能取得的最大价值加上第i件物品的价值。

根据第i件物品放或是不放确定遍历到第i件物品时的状态F[i][j]。

设物品件数为N,背包容量为V,第i件物品体积为C[i],第i 件物品价值为W[i]。

由此写出伪代码如下:[cpp]view plaincopy1.F[0][] ←{0}2.3.F[][0] ←{0}4.5.for i←1to N6.7.do for k←1to V8.9.F[i][k] ←F[i-1][k]10.11. if(k >= C[i])12.13. then F[i][k] ←max(F[i][k],F[i-1][k-C[i]]+W[i])14.15.return F[N][V]以上伪代码数组均为基于1索引,及第一件物品索引为1。

时间及空间复杂度均为O(VN)举例:表1-1为一个背包问题数据表,设背包容量为10根据上述解决方法可得到对应的F[i][j]如表1-2所示,最大价值即为F[6][10].表1-1背包问题数据表表1-2前i件物品选若干件放入空间为j的背包中得到的最大价值表很多文章讲背包问题时只是把最大价值求出来了,并没有把所选的是哪些物品找出来。

01背包问题动态规划算法

01背包问题动态规划算法

01背包问题动态规划算法
01背包问题是求在限定条件下,在一定的容量内最优装载物品,使得总价值最大。

动态规划算法是一种用于解决多阶段决策问题的途径,其特点是将原问题划分成若干子问题,每个子问题只求解一次,保存子问题的解,避免了重复计算。

01背包问题动态规划算法的步骤如下:
1、确定状态:物品的种数i (i=1,2,…n),背包的容量j (j=0,1,2,…V)。

2、确定状态转移方程:f[i][j]=max{f[i-1][j],f[i-1][j-wi]+vi}。

3、确定初始状态:f[i][0]=0,f[0][j]=0。

4、确定输出:最后f[n][V]即为最优解。

5、根据状态转移方程从左到右,从上到下进行迭代计算。

回溯法01背包问题

回溯法01背包问题

回溯法解决01背包问题







if(currentWeight+weight[i]<=c) { //将物品i放入背包,搜索左子树 bestAnswer[i] = 1; currentWeight += weight[i]; bestPrice += price[i]; Backtracking(i+1); //完成上面的递归,返回到上一结点,物 品i不放入背包,准备递归右子树 currentWeight -= weight[i]; bestPrice -= price[i]; } bestAnswer[i] = 0; Backtracking(i+1); }
回溯法解决01背包问题

0—1背包问题是一个子集选取问题,适合 于用子集树表示0—1背包问题的解空间。 在搜索解空间树是,只要其左儿子节点是 一个可行结点,搜索就进入左子树,在右 子树中有可能包含最优解是才进入右子树 搜索。否则将右子树剪去。
问题分析:


首先是将可供选择的物品的个数输入程序,将物品排成一列,计 算总物品的体积s,然后输入背包的实际体积V,如果背包的体积 小于0或者大于物品的总体积s,则判断输入的背包体积错误,否 则开始顺序选取物品装入背包,假设已选取了前i 件物品之后背包 还没有装满,则继续选取第i+1件物品,若该件物品"太大"不能装 入,则弃之而继续选取下一件,直至背包装满为止。但如果在剩 余的物品中找不到合适的物品以填满背包,则说明"刚刚"装入背包 的那件物品"不合适",应将它取出"弃之一边",继续再从"它之后" 的物品中选取,如此重复,直至求得满足条件的解。 因为回溯求解的规则是"后进先出",所以要用到栈来存储符合条件 的解,在存储过程中,利用数组来存储各个物品的体积,然后用 深度优先的搜索方式求解,将符合条件的数组元素的下标存入栈 里,最后得到符合条件的解并且实现输出。

0-1背包问题动态规划详解及代码

0-1背包问题动态规划详解及代码

0/1 背包问题动态规划详解及C代码动态规划是用空间换时间的一种方法的抽象。

其关键是发现子问题和记录其结果。

然后利用这些结果减轻运算量。

比如01背包问题。

/* 一个旅行者有一个最多能用M公斤的背包,现在有N件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为P1,P2,...,Pn.若每种物品只有一件求旅行者能获得最大总价值。

输入格式:M,NW1,P1W2,P2......输出格式:X*/因为背包最大容量M未知。

所以,我们的程序要从1到M一个一个的试。

比如,开始任选N 件物品的一个。

看对应M的背包,能不能放进去,如果能放进去,并且还有多的空间,则,多出来的空间里能放N-1物品中的最大价值。

怎么能保证总选择是最大价值呢?看下表。

测试数据:10,33,44,55,6c[i][j]数组保存了1,2,3号物品依次选择后的最大价值.这个最大价值是怎么得来的呢?从背包容量为0开始,1号物品先试,0,1,2,的容量都不能放.所以置0,背包容量为3则里面放4.这样,这一排背包容量为4,5,6,....10的时候,最佳方案都是放4.假如1号物品放入背包.则再看2号物品.当背包容量为3的时候,最佳方案还是上一排的最价方案c为4.而背包容量为5的时候,则最佳方案为自己的重量5.背包容量为7的时候,很显然是5加上一个值了。

加谁??很显然是7-4=3的时候.上一排 c3的最佳方案是4.所以。

总的最佳方案是5+4为9.这样.一排一排推下去。

最右下放的数据就是最大的价值了。

(注意第3排的背包容量为7的时候,最佳方案不是本身的6.而是上一排的9.说明这时候3号物品没有被选.选的是1,2号物品.所以得9.)从以上最大价值的构造过程中可以看出。

f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}这就是书本上写的动态规划方程.这回清楚了吗?下面是实际程序(在VC 6.0环境下通过):#include<stdio.h>int c[10][100];/*对应每种情况的最大价值*/int knapsack(int m,int n){int i,j,w[10],p[10];printf("请输入每个物品的重量,价值:\n");for(i=1;i<=n;i++)scanf("%d,%d",&w[i],&p[i]);for(i=0;i<10;i++)for(j=0;j<100;j++)c[i][j]=0;/*初始化数组*/for(i=1;i<=n;i++)for(j=1;j<=m;j++){if(w[i]<=j) /*如果当前物品的容量小于背包容量*/{if(p[i]+c[i-1][j-w[i]]>c[i-1][j])/*如果本物品的价值加上背包剩下的空间能放的物品的价值*//*大于上一次选择的最佳方案则更新c[i][j]*/c[i][j]=p[i]+c[i-1][j-w[i]];elsec[i][j]=c[i-1][j];}else c[i][j]=c[i-1][j];}return(c[n][m]);}int main(){int m,n;int i,j;printf("请输入背包的承重量,物品的总个数:\n");scanf("%d,%d",&m,&n);printf("旅行者背包能装的最大总价值为%d",knapsack(m,n)); printf("\n");return 0;}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

背包问题——“01背包”详解及实现(包含背包中具体物品的求解)分类:背包问题 2011-11-26 14:41 9554人阅读评论(10) 收藏举报pathtabledelete测试c算法-----Edit by ZhuSenlin HDU 01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为C1,C2,…,Cn,与之相对应的价值为W1,W2,…,Wn.求解将那些物品装入背包可使总价值最大。

动态规划(DP):1)子问题定义:F[i][j]表示前i件物品中选取若干件物品放入剩余空间为j的背包中所能得到的最大价值。

2)根据第i件物品放或不放进行决策(1-1)其中F[i-1][j]表示前i-1件物品中选取若干件物品放入剩余空间为j的背包中所能得到的最大价值;而F[i-1][j-C[i]]+W[i]表示前i-1件物品中选取若干件物品放入剩余空间为j-C[i]的背包中所能取得的最大价值加上第i件物品的价值。

根据第i件物品放或是不放确定遍历到第i件物品时的状态F[i][j]。

设物品件数为N,背包容量为V,第i件物品体积为C[i],第i 件物品价值为W[i]。

由此写出伪代码如下:[cpp]view plaincopy1.F[0][] ←{0}2.3.F[][0] ←{0}4.5.for i←1to N6.7.do for k←1to V8.9.F[i][k] ←F[i-1][k]10.11. if(k >= C[i])12.13. then F[i][k] ←max(F[i][k],F[i-1][k-C[i]]+W[i])14.15.return F[N][V]以上伪代码数组均为基于1索引,及第一件物品索引为1。

时间及空间复杂度均为O(VN)举例:表1-1为一个背包问题数据表,设背包容量为10根据上述解决方法可得到对应的F[i][j]如表1-2所示,最大价值即为F[6][10].表1-1背包问题数据表表1-2前i件物品选若干件放入空间为j的背包中得到的最大价值表很多文章讲背包问题时只是把最大价值求出来了,并没有把所选的是哪些物品找出来。

本人在学习背包问题之前遇到过很多的类似问题,当时也是只求得了最大价值或最大和,对具体哪些物品或路径等细节也束手无策。

再次和大家一起分享细节的求法。

根据算法求出的最大价值表本身其实含有位置信息,从F[N][V]逆着走向F[0][0],设i=N,j=V,如果F[i][j]==F[i-1][j- C[i]]+W[i]说明包里面有第i件物品,同时j -= C[i],不管F[i][j]与F[i-1][j-C[i]]+W[i]相不相等i都要减1,因为01背包的第i件物品要么放要么不放,不管放还是不放其已经遍历过了,需要继续往下遍历。

打印背包内物品的伪代码如下:[cpp]view plaincopy1.i←N2.3.j←V4.5.while(i>0 && j>0)6.7.do if(F[i][j]=F[i-1][j-C[i]]+W[i])8.9.then Print W[i]10.11. j←j-C[i]12.13. i←i-1当然也可以定义一个二维数组Path[N][V]来存放背包内物品信息,开始时Path[N][V]初始化为0,当 F[i][j]==F[i-1][j-C[i]]+W[i]时Path[i][j]置1。

最后通过从Path[N+1][V+1]逆着走向Path[0] [0]来获取背包内物品。

其中Path[0][]与Path[][0]为边界。

加入路径信息的伪代码如下:[cpp]view plaincopy1.F[0][] ←{0}2.3.F[][0] ←{0}4.5.Path[][] ←06.7.for i←1to N8.9.do for k←1to V10.11. F[i][k] ←F[i-1][k]12.13. if(k >= C[i] && F[i][k] < F[i-1][k-C[i]]+W[i])14.15. then F[i][k] ←F[i-1][k-C[i]]+W[i]16.17. Path[i][k] ← 118.19.return F[N][V] and Path[][]打印背包内物品的伪代码如下:[cpp]view plaincopy1.i←N2.3.j←V4.5.while(i>0 && j>0)6.7.do if(Path[i][j] = 1)8.9.then Print W[i]10.11. j←j-C[i]12.13. i←i-1在时间及空间复杂度均为O(NV)的情况下,利用Path[][]的方法明显比直接通过F[i][j]==F[i-1][j-C[i]]+W[i]来打印物品耗费空间,Path[][]需要额外的空间O(NV)但总空间复杂度不变仍为O(NV)。

但下面要讲到的O(V)的空间复杂度的方法却不能利用关系式 F [j]==F [j-C[i]]+W[i]而只能利用Path[][]进行标记.接下来考虑如何压缩空间,以降低空间复杂度。

时间复杂度为O(VN),空间复杂度将为O(V)观察伪代码可也发现,F[i][j]只与F[i-1][j]和F[i-1][j-C[i]]有关,即只和i-1时刻状态有关,所以我们只需要用一维数组F[]来保存i-1时的状态F[]。

假设i-1时刻的F[]为{a0,a1,a2,…,av},难么i时刻的F[]中第k个应该为max(ak ,ak-C[i]+W[i]) 即max(F[k],F[k-C[i]]+W[i]),这就需要我们遍历V时逆序遍历,这样才能保证求i时刻F[k]时F[k-C[i]]是i-1时刻的值。

如果正序遍历则当求F[k]时其前面的F[0],F[1],…,F[K-1]都已经改变过,里面存的都不是i-1时刻的值,这样求F[k]时利用 F[K-C[i]]必定是错的值。

最后F[V]即为最大价值。

求F[j]的状态方程如下:(1-2)伪代码如下:[cpp]view plaincopy1.F[] ←{0}2.3.for i ← 1 to N4.5.do for k ←V to C[i]6.7.F[k] ←max(F[k],F[k-C[i]]+W[i])8.9.return F[V]同样,怎么求路径?利用前面讲到的Path[][]标记,需空间消耗O(NV)。

这里不能用F [j]==F [j-C[i]]+W[i]来判断是因为一维数组并不能提供足够的信息来寻找二维路径。

加入路径信息的伪代码如下:[cpp]view plaincopy1.F[] ←{0}2.3.Path[][]←04.5.for i←1to N6.7.do for k←V to C[i]8.9.if(F[k] < F[k-C[i]]+W[i])10.11. then F[k] ←F[k-C[i]]+W[i]12.13. Path[i][k] ← 114.15.return F[V] and Path[][]打印路径的伪代码和前面未压缩空间复杂度时的伪代码一样,这里不再重写。

下面针对前面提到的表1-1提供两种方法的测试代码:[cpp]view plaincopy1.#include <iostream>2.#include <cstring>3.#include "CreateArray.h" //该头文件用于动态创建及销毁二维数组,读者自己实现ing namespace std;//时间复杂度O(VN),空间复杂度为O(VN)[cpp]view plaincopy1.int Package01(int Weight[], int Value[], int nLen, intnCapacity)2.{3.int** Table = NULL;4.int** Path = NULL;5.CreateTwoDimArray(Table,nLen+1,nCapacity+1); //创建二维数组6.CreateTwoDimArray(Path,nLen+1,nCapacity+1); //创建二维数组7.8.for(int i = 1; i <= nLen; i++)9.{10. for(int j = 1; j <= nCapacity; j++)11. {12. Table[i][j] = Table[i-1][j];13. Path[i][j] = 0;14. if(j >= Weight[i-1] && Table[i][j]< Table[i-1][j-Weight[i-1]]+Value[i-1])15. {16. Table[i][j] = Table[i-1][j-Weight[i-1]]+Value[i-1];17. Path[i][j] = 1;18. }19. }20. }21.22. int i = nLen, j = nCapacity;23. while(i > 0 && j > 0)24. {25. if(Path[i][j] == 1)26. {27. cout << Weight[i-1] << " ";28. j -= Weight[i-1];29. }30. i--;31. }32. cout << endl;33.34. int nRet = Table[nLen][nCapacity];35. DestroyTwoDimArray(Table,nLen+1); //销毁二维数组36. DestroyTwoDimArray(Path,nLen+1); //销毁二维数组37. return nRet;38.}//时间复杂度O(VN),不考虑路径空间复杂度为O(V),考虑路径空间复杂度为O(VN)[cpp]view plaincopy1.int Package01_Compress(int Weight[], int Value[], int nLen, int nCapacity)2.{3.int * Table = new int [nCapacity+1];4.memset(Table,0,(nCapacity+1)*sizeof(int));5.int** Path = 0;6.CreateTwoDimArray(Path,nLen+1,nCapacity+1); //创建二维数组7.8.for(int i = 0; i < nLen; i++)9.{10. for(int j = nCapacity; j >= Weight[i]; j--)11. {12. Path[i+1][j] = 0;13. if(Table[j] < Table[j-Weight[i]]+Value[i])14. {15. Table[j] = Table[j-Weight[i]]+Value[i];16. Path[i+1][j] = 1;17. }18. }19. }20.21. int i = nLen, j = nCapacity;22. while(i > 0 && j > 0)23. {24. if(Path[i][j] == 1)25. {26. cout << Weight[i-1] << " ";27. j -= Weight[i-1];28. }29.30. i--;31. }32. cout << endl;33.34. int nRet = Table[nCapacity];35. DestroyTwoDimArray(Path,nLen+1); //销毁二维数组36. delete [] Table;37. return nRet;38.}测试代码[cpp]view plaincopy1.int main()2.{3.int Weight[] = {2,3,1,4,6,5};4.int Value[] = {5,6,5,1,19,7};5.int nCapacity = 10;6.cout << Package01(Weight,Value,sizeof(Weight)/sizeof(int),nCapacity) << endl;7.cout << Package01_Compress(Weight,Value,sizeof(Weight)/sizeof(int),nCapacity) << endl;。

相关文档
最新文档