0-1背包问题c语言程序

合集下载

0-1背包问题的多种解法

0-1背包问题的多种解法

问题描述0/1 背包问题 :现有 n 种物品,对 1<=i<=n ,已知第 i 种物品的重量为正整数 W i ,价值为正整数 V i , 背包能承受的最大载重量为正整数 W ,现要求找出这 n 种物品的一个子集,使得子集中物 品的总重量不超过 W 且总价值尽量大。

(注意:这里对每种物品或者全取或者一点都不取, 不允许只取一部分)算法分析根据问题描述,可以将其转化为如下的约束条件和目标函数:nw i x i W i 1 i i(1)x i { 0,1}( 1 i n)nmax v i x i (2) i1于是,问题就归结为寻找一个满足约束条件( 1 ),并使目标函数式( 2 )达到最大的 解向量 X (x 1, x 2 ,x 3, ........... , x n ) 。

首先说明一下 0-1 背包问题拥有最优解。

假设 (x 1,x 2,x 3, ........ ,x n ) 是所给的问题的一个最优解, 则(x 2,x 3, ............... ,x n )是下面问题的n n n个问 题 的 一 个 最 优解 , 则v i y iv i x i , 且 w 1x 1w i y i W 。

因此 ,i 2 i 2 i 2一个最优解:w i x i Wi2w 1x 1nmax v i x i 。

如果不是的话,设(y 2,y 3, , y n ) 是这x i {0,1}( 2 i n)i2n n nv1x1 v i y i v1x1 v i x i v i x i ,这说明(x1,y2,y3, ............. ,y n) 是所给的0-1 背包问i 2 i 2 i 1题比( x1 , x 2 , x3 , ... , x n ) 更优的解,从而与假设矛盾。

穷举法:用穷举法解决0-1 背包问题,需要考虑给定n 个物品集合的所有子集,找出所有可能的子集(总重量不超过背包重量的子集) ,计算每个子集的总重量,然后在他们中找到价值最大的子集。

2019年下半年软件设计师下午案例分析真题(试题四)

2019年下半年软件设计师下午案例分析真题(试题四)

2019年下半年软件设计师下午案例分析真题(试题四)
4、阅读下列说明和C代码,回答问题1至问题3。

【说明】
0-1背包问题定义为:给定i个物品的价值v[1…i]、小重量w[1...i]和背包容量T,每个物品装到背包里或者不装到背包里。

求最优的装包方案,使得所得到的价值最大。

0-1背包问题具有最优子结构性质。

定义c[i][T]为最优装包方案所获得的最大价值,则可得到如下所示的递归式。

【c代码】
下面是算法的C语言实现。

(1)常量和变量说明
T: 背包容量
v[]:价值数组
w[]:重量数组
c[][]:c[i][j]表示前i个物品在背包容量为j的情况下最优装包方案所能获得的最大价值
(2) C程序
【问题1】(8分)
根据说明和C代码,填充C代码中的空(1) ~ (4)。

【问题2】(4分)
根据说明和C代码,算法采用了(5) 设计策略。

在求解过程中,采用了(6)(自底向上或者自顶向下)的方式。

【问题3】(3分)
若5项物品的价值数组和重量数组分别为v[]= {0,1,6,18,22,28}和w[]= {0,1,2,5,6,7}背包容量为T= 11,则获得的最大价值为(7)。

分支限界法求0-1背包问题实验程序以及代码(C++)

分支限界法求0-1背包问题实验程序以及代码(C++)

分支限界法求0-1背包问题实验程序以及代码(C++)本程序中(规定物品数量为3,背包容量为30,输入为6个数,前3个为物品重量,后3个数为物品价值):代码:#include<iostream>#include<stack>using namespace std;#define N 100classHeapNode //定义HeapNode结点类{public:doubleupper,price,weight; //upper为结点的价值上界,price是结点所对应的价值,weight为结点所相应的重量int level,x[N]; //活节点在子集树中所处的层序号};double MaxBound(int i);double Knap();void AddLiveNode(double up,double cp,double cw,bool ch,int level);stack<HeapNode>High; //最大队Highdouble w[N],p[N]; //把物品重量和价值定义为双精度浮点数double cw,cp,c=30; //cw为当前重量,cp为当前价值,定义背包容量为30int n=3; //货物数量为3int main(){cout<<"请按顺序输入3个物品的重量:(按回车键区分每个物品的重量)"<<endl;int i;for(i=1;i<=n;i++)cin>>w[i]; //输入3个物品的重量cout<<"请按顺序输入3个物品的价值:(按回车键区分每个物品的价值)"<<endl;for(i=1;i<=n;i++)cin>>p[i]; //输入3个物品的价值cout<<"最大价值为:";cout<<Knap()<<endl; //调用knap函数输出最大价值return 0;}double MaxBound(int j) //MaxBound函数求最大上界{doubleleft=c-cw,b=cp; //剩余容量和价值上界while(j<=n&&w[j]<=left) //以物品单位重量价值递减装填剩余容量{left-=w[j];b+=p[j];j++;}if(j<=n)b+=p[j]/w[j]*left; //装填剩余容量装满背包return b;}void AddLiveNode(double up,double cp,double cw,bool ch,int lev)//将一个新的活结点插入到子集数和最大堆High中{HeapNode be;be.upper=up;be.price=cp;be.weight=cw;be.level=lev;if(lev<=n)High.push(be); //调用stack头文件的push函数}double Knap() //优先队列分支限界法,返回最大价值,bestx返回最优解{ int i=1; cw=cp=0; doublebestp=0,up=MaxBound(1); //调用MaxBound求出价值上界,best为最优值while(1) //非叶子结点{ double wt=cw+w[i];if(wt<=c) //左儿子结点为可行结点{ if(cp+p[i]>bestp) bestp=cp+p[i];AddLiveNode(up,cp+p[i],cw+w[i],true,i+1);}up=MaxBound(i+1);if(up>=bestp) //右子数可能含最优解AddLiveNode(up,cp,cw,false,i+1);if(High.empty()) return bestp;HeapNode node=High.top(); //取下一扩展结点High.pop(); cw=node.weight; cp=node.price; up=node.upper; i=node.level;}}输出结果为:。

01背包问题c语言代码回溯法

01背包问题c语言代码回溯法

以下是使用C语言实现01背包问题的回溯法代码:```c#include <stdio.h>#include <stdlib.h>// 初始化背包struct knapsack {int maxWeight; // 背包最大承重int *items; // 物品数组int n; // 物品数量};// 定义物品重量、价值和数量int weights[] = {2, 2, 6, 5, 4};int values[] = {6, 3, 5, 4, 6};int quantities[] = {3, 2, 2, 1, 1};// 初始化背包最大承重和当前承重int maxWeight = 10;int currentWeight = 0;// 初始化最大价值为0int maxValue = 0;// 遍历物品数组void traverseItems(struct knapsack *knapsack, int index) { // 对于每个物品,遍历其数量for (int i = 0; i < knapsack->quantities[index]; i++) {// 如果当前物品可以放入背包装且当前承重不超过背包最大承重,计算放入该物品后的总价值,并更新最大价值if (currentWeight + weights[index] <= knapsack->maxWeight) {int currentValue = values[index] * knapsack->quantities[index];if (currentValue > maxValue) {maxValue = currentValue;}}// 回溯,将当前物品从背包装中移除,递归地尝试下一个物品knapsack->quantities[index]--;if (index < knapsack->n - 1) {traverseItems(knapsack, index + 1);}knapsack->quantities[index]++; // 恢复物品数量,以便下次遍历尝试放入其他物品}}// 主函数int main() {// 初始化背包装和物品数组struct knapsack knapsack = {maxWeight, weights, 5};knapsack.items = (int *)malloc(sizeof(int) * knapsack.n);for (int i = 0; i < knapsack.n; i++) {knapsack.items[i] = values[i] * quantities[i]; // 根据价值和数量计算物品价值,并存储在物品数组中}knapsack.n = quantities[4]; // 由于最后一个物品的数量为1,因此只需遍历前n-1个物品即可得到所有可能的结果// 使用回溯法求解01背包问题,返回最大价值traverseItems(&knapsack, 0);printf("The maximum value is %d.\n", maxValue);free(knapsack.items); // 释放内存空间return 0;}```希望以上信息能帮助到你。

c语言算法--贪婪算法---01背包问题

c语言算法--贪婪算法---01背包问题

c语言算法--贪婪算法---0/1背包问题在0 / 1背包问题中,需对容量为c 的背包进行装载。

从n 个物品中选取装入背包的物品,每件物品i 的重量为wi ,价值为pi 。

对于可行的背包装载,背包中物品的总重量不能超过背包的容量,最佳装载是指所装入的物品价值最高,即n ?i=1pi xi 取得最大值。

约束条件为n ?i =1wi xi≤c 和xi?[ 0 , 1 ] ( 1≤i≤n)。

在这个表达式中,需求出xt 的值。

xi = 1表示物品i 装入背包中,xi =0 表示物品i 不装入背包。

0 / 1背包问题是一个一般化的货箱装载问题,即每个货箱所获得的价值不同。

货箱装载问题转化为背包问题的形式为:船作为背包,货箱作为可装入背包的物品。

例1-8 在杂货店比赛中你获得了第一名,奖品是一车免费杂货。

店中有n 种不同的货物。

规则规定从每种货物中最多只能拿一件,车子的容量为c,物品i 需占用wi 的空间,价值为pi 。

你的目标是使车中装载的物品价值最大。

当然,所装货物不能超过车的容量,且同一种物品不得拿走多件。

这个问题可仿照0 / 1背包问题进行建模,其中车对应于背包,货物对应于物品。

0 / 1背包问题有好几种贪婪策略,每个贪婪策略都采用多步过程来完成背包的装入。

在每一步过程中利用贪婪准则选择一个物品装入背包。

一种贪婪准则为:从剩余的物品中,选出可以装入背包的价值最大的物品,利用这种规则,价值最大的物品首先被装入(假设有足够容量),然后是下一个价值最大的物品,如此继续下去。

这种策略不能保证得到最优解。

例如,考虑n=2, w=[100,10,10], p =[20,15,15], c = 1 0 5。

当利用价值贪婪准则时,获得的解为x= [ 1 , 0 , 0 ],这种方案的总价值为2 0。

而最优解为[ 0 , 1 , 1 ],其总价值为3 0。

另一种方案是重量贪婪准则是:从剩下的物品中选择可装入背包的重量最小的物品。

0-1背包问题-贪心法和动态规划法求解

0-1背包问题-贪心法和动态规划法求解

实验四“0-1”背包问题一、实验目的与要求熟悉C/C++语言的集成开发环境;通过本实验加深对贪心算法、动态规划算法的理解。

二、实验内容:掌握贪心算法、动态规划算法的概念和基本思想,分析并掌握“0-1”背包问题的求解方法,并分析其优缺点。

三、实验题1.“0-1”背包问题的贪心算法2.“0-1”背包问题的动态规划算法说明:背包实例采用教材P132习题六的6-1中的描述。

要求每种的算法都给出最大收益和最优解。

设有背包问题实例n=7,M=15,,(w0,w1,。

w6)=(2,3,5,7,1,4,1),物品装入背包的收益为:(p0,p1,。

,p6)=(10,5,15,7,6,18,3)。

求这一实例的最优解和最大收益。

四、实验步骤理解算法思想和问题要求;编程实现题目要求;上机输入和调试自己所编的程序;验证分析实验结果;整理出实验报告。

五、实验程序// 贪心法求解#include<iostream>#include"iomanip"using namespace std;//按照单位物品收益排序,传入参数单位物品收益,物品收益和物品重量的数组,运用冒泡排序void AvgBenefitsSort(float *arry_avgp,float *arry_p,float *arry_w ); //获取最优解方法,传入参数为物品收益数组,物品重量数组,最后装载物品最优解的数组和还可以装载物品的重量float GetBestBenifit(float*arry_p,float*arry_w,float*arry_x,float u);int main(){float w[7]={2,3,5,7,1,4,1}; //物品重量数组float p[7]={10,5,15,7,6,18,3}; //物品收益数组float avgp[7]={0}; //单位毒品的收益数组float x[7]={0}; //最后装载物品的最优解数组const float M=15; //背包所能的载重float ben=0; //最后的收益AvgBenefitsSort(avgp,p,w);ben=GetBestBenifit(p,w,x,M);cout<<endl<<ben<<endl; //输出最后的收益system("pause");return 0;}//按照单位物品收益排序,传入参数单位物品收益,物品收益和物品重量的数组,运用冒泡排序void AvgBenefitsSort(float *arry_avgp,float *arry_p,float *arry_w ) {//求出物品的单位收益for(int i=0;i<7;i++){arry_avgp[i]=arry_p[i]/arry_w[i];}cout<<endl;//把求出的单位收益排序,冒泡排序法int exchange=7;int bound=0;float temp=0;while(exchange){bound=exchange;exchange=0;for(int i=0;i<bound;i++){if(arry_avgp[i]<arry_avgp[i+1]){//交换单位收益数组temp=arry_avgp[i];arry_avgp[i]=arry_avgp[i+1];arry_avgp[i+1]=temp;//交换收益数组temp=arry_p[i];arry_p[i]=arry_p[i+1];arry_p[i+1]=temp;//交换重量数组temp=arry_w[i];arry_w[i]=arry_w[i+1];arry_w[i+1]=temp;exchange=i;}}}}//获取最优解方法,传入参数为物品收益数组,物品重量数组,最后装载物品最优解的数组和还可以装载物品的重量float GetBestBenifit(float*arry_p,float*arry_w,float*arry_x,float u) {int i=0; //循环变量ifloat benifit=0; //最后收益while(i<7){if(u-arry_w[i]>0){arry_x[i]=arry_w[i]; //把当前物品重量缴入最优解数组benifit+=arry_p[i]; //收益增加当前物品收益u-=arry_w[i]; //背包还能载重量减去当前物品重量cout<<arry_x[i]<<" "; //输出最优解}i++;}return benifit; //返回最后收益}//动态规划法求解#include<stdio.h>#include<math.h>#define n 6void DKNAP(int p[],int w[],int M,const int m); void main(){int p[n+1],w[n+1];int M,i,j;int m=1;for(i=1;i<=n;i++){m=m*2;printf("\nin put the weight and the p:");scanf("%d %d",&w[i],&p[i]);}printf("%d",m);printf("\n in put the max weight M:");scanf("%d",&M);DKNAP(p,w,M,m);}void DKNAP(int p[],int w[],int M,const int m) {int p2[m],w2[m],pp,ww,px;int F[n+1],pk,q,k,l,h,u,i,j,next,max,s[n+1];F[0]=1;p2[1]=w2[1]=0;l=h=1;F[1]=next=2;for(i=1;i<n;i++){k=l;max=0;u=l;for(q=l;q<=h;q++)if((w2[q]+w[i]<=M)&&max<=w2[q]+w[i]){u=q;max=w2[q]+w[i];}for(j=l;j<=u;j++){pp=p2[j]+p[i];ww=w2[j]+w[i];while(k<=h&&w2[k]<ww){p2[next]=p2[k];w2[next]=w2[k];next++;k++;}if(k<=h&&w2[k]==ww){if(pp<=p2[k])pp=p2[k];k++;}else if(pp>p2[next-1]){p2[next]=pp;w2[next]=ww;next++;}while(k<=h&&p2[k]<=p2[next-1])k++;}while(k<=h){p2[next]=p2[k];w2[next]=w2[k];next=next+1;k++;}l=h+1;h=next-1;F[i+1]=next;}for(i=1;i<next;i++)printf("%2d%2d ",p2[i],w2[i]);for(i=n;i>0;i--){next=F[i];next--;pp=pk=p2[next];ww=w2[next];while(ww+w[i]>M&&next>F[i-1]){next=next-1;pp=p2[next];ww=w2[next];}if(ww+w[i]<=M&&next>F[i-1])px=pp+p[i];if(px>pk&&ww+w[i]<=M){s[i]=1;M=M-w[i];printf("M=%d ",M);}else s[i]=0;}for(i=1;i<=n;i++)printf("%2d ",s[i]);}六、实验结果1、贪心法截图:七、实验分析。

0-1背包问题动态规划和贪心法实现

0-1背包问题动态规划和贪心法实现

算法设计与分析实验报告实验二 0-1背包问题院系:班级:计算机科学与技术学号:姓名:任课教师:成绩:湘潭大学2016年5月实验二0-1背包问题一. 实验内容分别编程实现动态规划算法和贪心法求0-1背包问题的最优解,分析比较两种算法的时间复杂度并验证分析结果。

二.实验目的1、掌握动态规划算法和贪心法解决问题的一般步骤,学会使用动态规划和贪心法解决实际问题;2、理解动态规划算法和贪心法的异同及各自的适用范围。

三. 算法描述/*动态规划 0-1背包问题算法如下*/Template<class Type>Void Knapsack(Type v,int w,int c,int n,Type ** m){int jMax = min(w[n] - 1,c);For(int j = 0;j <= jMax;j++){m[n][j] = 0;}For(int j = w[n];j <= c;j++){m[n][j] = v[n];}For(int i = n- 1;i > 1;i--){jMax = min(w[i] - 1,c);For(int j = 0;j <= jMax;j++) m[i][j] = m[i+1][j];For(int j = w[i];j <= c;j++) min[i][j] = max(m[i+1][j],m[i+1][j-w[i]]+v[i]);}m[1][c] = m[2][c];If(c >= w[1]) m[1][c] = max(m[1][c],m[2][c-w[1]]+v[1]);}Template<class Type>Void Traceback(Type**m,int w,int c,int n,int x){for(int i =1 ;i < n;i ++)If(m[i][c] == m[i+1][c]) x[i] = 0;Else{x[i] = 1;c -=w[i];}x[n] = (m[n][c]) ? 1:0;}按上述算法Knapsack计算后m[1][c]给出所要求的0-1背包问题的最优解。

C语言动态规划之背包问题详解

C语言动态规划之背包问题详解

C语⾔动态规划之背包问题详解01背包问题给定n种物品,和⼀个容量为C的背包,物品i的重量是w[i],其价值为v[i]。

问如何选择装⼊背包的物品,使得装⼊背包中的总价值最⼤?(⾯对每个武平,只能有选择拿取或者不拿两种选择,不能选择装⼊某物品的⼀部分,也不能装⼊物品多次)声明⼀个数组f[n][c]的⼆维数组,f[i][j]表⽰在⾯对第i件物品,且背包容量为j时所能获得的最⼤价值。

根据题⽬要求进⾏打表查找相关的边界和规律根据打表列写相关的状态转移⽅程⽤程序实现状态转移⽅程真题演练:⼀个旅⾏者有⼀个最多能装M公⽄的背包,现在有n件物品,它们的重量分别是W1、W2、W3、W4、…、Wn。

它们的价值分别是C1、C3、C2、…、Cn,求旅⾏者能获得最⼤价值。

输⼊描述:第⼀⾏:两个整数,M(背包容量,M<= 200)和N(物品数量,N<=30);第2…N+1⾏:每⾏两个整数Wi,Ci,表⽰每个物品的质量与价值。

输出描述:仅⼀⾏,⼀个数,表⽰最⼤总价值样例:输⼊:10 42 13 34 57 9输出:12解题步骤定义⼀个数组dp[i][j]表⽰容量为j时,拿第i个物品时所能获取的最⼤价值。

按照题⽬要求进⾏打表,列出对应的dp表。

W[i](质量)V[i](价值)01234567891000000000000210011111111133001334444444500135568899790013556991012对于⼀个动态规划问题设置下标时最好从0开始,因为动态规划经常会和上⼀个状态有关系!从上⾯的dp表可以看出来对于⼀个物品我们拿还是不难需要进⾏两步来判断。

第⼀步:判断背包当前的容量j是否⼤于物品当前的质量,如果物品的质量⼤于背包的容量那么就舍弃。

第⼆步:如果背包可以装下这个物品,就需要判断装下该物品获取的最⼤价值是不是⼤于不装下这个物品所获取的最⼤价值,如果⼤于那么就把东西装下!根据这样的思想我们可以得到状态转移⽅程:如果单签背包的容量可以装下物品:dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);如果当前背包的容量装不下该物品:dp[i][j]=dp[i-1][j];#include <stdio.h>int max(const int a,const int b){return a>b ? a:b;}int main(){int w[35]={0},v[35]={0},dp[35][210]={0};int n,m;scanf("%d %d",&m,&n);int i,j;for(i=1;i<=n;i++){scanf("%d %d",&w[i],&v[i]);}for(i=1;i<=n;i++){for(j=1;j<=m;j++){if(j>=w[i])//如果当前背包的容量⼤于商品的质量{dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);//判断是否应该拿下}else//⼤于背包的当前容量{dp[i][j]=dp[i-1][j];}}}for(int k=0;k<=n;k++){for(int l=0;l<=m;l++){printf("%d ",dp[k][l]);}printf("\n");}printf("%d\n",dp[n][m]);}通过运⾏以上程序可以看到最终的输出dp表和我们的预期是相符合的!但是并没有结束,动态规划有⼀个后⽆效性原则(当前状态只与前⼀个状态有关)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
printf("%3d ",c[i][j]);
if(j==m)
printf("\n");
}
getbest(m,n,w,p);
printf("最优n元0-1向量为:\n");
for(i=1;i<=n;i++)
printf("x%d ",i);
printf("\n");
//打印最优n元0-1向量(x1,x2,x3……,xn)
w=(int *)calloc(n,sizeof(int));//分配n*sizeof(int)的内存大小,存取n个物品的质量
if(!p||!w)//检测分配是否成功
{
printf("Not Enough Memory!\n");
exit(1);//分配失败,退出
}
for(int i=1;i<n+1;i++)
{
printf("物品x%d的重量和价值:",i);
scanf("%d%d",w+i,p+i);
}
printf("\n总价值最大为:%d",knapsack(m,n,w,p));
printf("\n");
for(ห้องสมุดไป่ตู้=0;i<=n;i++)//打印执行动态规划每步的值
for(int j=0;j<=m;j++)
}
else //i号物品重量大于剩余容量,不能再放i号物品
c[i][j]=c[i-1][j];
}
return(c[n][m]);//最后的值即为最优值,返回主函数
}
//求最优n元0-1向量(x1,x2,x3……,xn)
int getbest(int m,int n,int *w,int *p)
{
if(n==0)return 0;//递归,每次递归n减1,n为0时退出
if(x[n])
getbest(m-w[n],n-1,w,p);
else
getbest(m,n-1,w,p);
}
}
void main()
{
int m,n;
int *w=NULL;
int *p=NULL;
printf("输入背包容量和货物个数:");
scanf("%d%d",&m,&n);
p=(int *)calloc(n,sizeof(int));//分配n*sizeof(int)的内存大小,存取n个物品的价格
{
bool a;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(w[i]<=j)
{ a=p[i]+c[i-1][j-w[i]]>c[i-1][j];
c[i][j]=a?p[i]+c[i-1][j-w[i]]:c[i-1][j];
//前者表示放i物品,后者表示不放i物品
{
bool a;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(w[i]<=j)
{ a=p[i]+c[i-1][j-w[i]]>c[i-1][j];
c[i][j]=a?p[i]+c[i-1][j-w[i]]:c[i-1][j];
//前者表示放i物品,后者表示不放i物品
0-1背包问题
问题描述
给定n种物品和一背包,物品i的重量是wi,其价值是pi,背包的容量是M,如何选择装入背包中的物品总价值最大?
问题分析
记c[i][m]表示前i个物品,在背包容量大小为m的情况下,最大的装载量。
如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为m的背包中”,价值为c[i-1][m];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为m-w[i]的背包中”,此时能获得的最大价值就是c[i-1][m-w[i]]再加上通过放入第i件物品获得的价值p[i]。因为背包最大容量M未知。所以,我们的程序要从1到M一个一个的试。比如,开始任选N件物品的一个。看对应M的背包,能不能放进去,如果能放进去,并且还有多的空间,则多出来的空间里能放N-1物品中的最大价值。从以上最大价值的构造过程中可以看出:
if(x[n])
getbest(m-w[n],n-1,w,p);
else
getbest(m,n-1,w,p);
}
}
程序:
#include<stdio.h>
#include<stdlib.h>
int c[15][25];//全局变量,初始值全为0
bool x[25];//x数组存n元0-1向量
int knapsack(int m,int n,int *w,int *p)
c(n,m)=max{c(n-1,m),c(n-1,m-w[n])+p(n)
其中c[i-1][m]表示第i件物品不装入背包中,而c[i-1][m-w[i]] + p[i]表示第i件物品装入背包中。
伪代码:
1.最优值max(x1*p1+x2*p2+……xn*pn)
int knapsack(int m,int n,int *w,int *p)
}
else //i号物品重量大于剩余容量,不能再放i号物品
c[i][j]=c[i-1][j];
}
return(c[n][m]);//最后的值即为最优值,返回主函数
}
2.求最优n元0-1向量(x1,x2,x3……,xn)
int getbest(int m,int n,int *w,int *p)
{
if(n==0)return 0;//递归,每次递归n减1,n为0时退出
for(i=1;i<=n;i++)
printf("%-4d",x[i]);
printf("\n");
}
运行结果:
if(w[n]>m)
{
x[n]=0;
getbest(m,n-1,w,p);
}
else
{
//如果c[n][m]由p[n]+c[n-1][m-w[n]]而来,则x[n]=1;
//如果c[n][m]由c[n-1][m]]而来,则x[n]=0;
x[n]=c[n-1][m]<=p[n]+c[n-1][m-w[n]];
if(w[n]>m)
{
x[n]=0;
getbest(m,n-1,w,p);
}
else
{
//如果c[n][m]由p[n]+c[n-1][m-w[n]]而来,则x[n]=1;
//如果c[n][m]由c[n-1][m]]而来,则x[n]=0;
x[n]=c[n-1][m]<=p[n]+c[n-1][m-w[n]];
相关文档
最新文档