1.背包可以分为哪几类

2.电脑背包什么牌子好?

3.有哪些适合装笔记本电脑、适合上下班通勤的平价大包推荐?

4.0-1背包问题的多种解法代码(动态规划、贪心法、回溯法、分支限界法)

背包可以分为哪几类

怎么样开发电脑系统背包功能-怎么样开发电脑系统背包

摘要:双肩包是对背在双肩的背包的统称。根据双肩包不同的用途又分成,双肩电脑背包,双肩运动背包,双肩休闲背包,双肩书包和束口绳包,军用背包,登山包等等。今天,小编主要向大家介绍电脑双肩包,运动双肩包,时尚双肩包这些背包的特点和用途。背包种类背包的种类及用途背包可以分为哪几类背包可以分为哪几类

电脑双肩包

全球电脑包巨头HTTP公司于上世纪八十年代即推出了世界第一款双肩电脑包,由于用了防震保护材料,加上特别的人体工程学设计和独特加固制作工艺,极为坚实耐用,深受欢迎。电脑双肩包除了有专门用于装电脑的防震保护隔层,也有相当大空间可以用于装行李等小物件。许多高品质的电脑双肩包也被广泛当做运动旅行包使用。

运动双肩包

运动双肩包设计上非常跳跃,颜色较为鲜艳。主要运动品牌耐克、阿迪达斯、李宁、鸿星尔克、等每年都会推出大量新款时尚双肩包,受到一大批20岁上下的潮男潮女追捧。运动双肩包在材质和做工上因为功能不同在质量上也有所差别。比如一些大品牌的双肩包在面料和款式革新上,功能上也得到了扩展,户外用的双肩包就具备防水功能。

时尚双肩包

时尚双肩包主要为女士使用,多数是由PU材料做成,也有帆布面料做成的,体积有大有小,PU面料的包通常用来替代女士出门必带的手提包,而帆布面料的双肩包也为中小学生所喜爱,用作上学书包。时尚双肩包适较为合在穿着休闲的女士出门时携带。时尚双肩包方便携带,彻底解放双手,也非常适合女士在非正式场合使用。

背包的保养常识

第一:不要一直背着,如果你进行的是长时间的运动的话,最好不要选择长时间背着你的双肩包了,必定,这样长时间的背着对你的身体也是不好的,要尝试着在一两个小时之后进行手提,然后再背上,这样劳逸结合对待你的包,可以很大程度上延长你的背包的寿命。

第二:要经常让你的包见到太阳,不要一直放在屋里面不进行户外运动哦。没有太阳光线的滋润,你的包包就可能会出现发霉的情况,同时还会出现一些异味,让人闻起来感到非常的不舒服,何况你还要背着它呢,所以,不妨隔一段时间就把你的爱包拿出来进行一个日光浴,给它一点阳光呢?

第三:尽量避免大幅度的摩擦,在使用的过程中,难免会遇到一些磨损的,这里不是说不能磨损,而是尽量的去减少磨损带给你的损害,要做到少磨损多爱护。尽量避开摩擦力较大或者表面不平滑的地方去使用,如果一定要用,也要多留一个心眼,情非得已千万不要进行正面的摩擦哦。

电脑背包什么牌子好?

问题一:电脑包什么牌子好 10分 下面回答的都有没看细看问题就回答了,真正原装电脑包质量还可以,但是款式一般不好看,电脑包品牌做得好的有瑞士军刀 美国森泰斯 意大利托卡诺等等。各有各的强势。背包军刀,公文森泰斯和托卡诺。但是款式来看,森泰斯的会比较多,更时尚一些。希望这些对你有所帮助。

1、中高端电脑包什么牌子好:瑞士军刀、LIOVO雷洛、金圣斯、森泰斯、Dewar的沃、瑞士军刀、FEGER/斐格、伦威保罗、泰格斯、托卡诺、泰伦斯、米莱恩、天盾、富力狮、优配等;中低端:

VIAVIAT(威尔维特)等;

2、电脑包什么牌子好OEM包:即各品牌笔记本自带的电脑包,如著名的IBM红点包、SONY包等(由泰格斯、森泰斯的品牌代工);

3、电脑包什么牌子好参差不齐的仿冒包,从款式,颜色LOGO、掉牌等方面都有仿冒,甚至商标都有仿的很像的。

什么牌子的电脑包好.哪个牌子的电脑包好.电脑包哪个牌子好.电脑包什么品牌好.电脑包双肩.双肩电脑包.什么电脑包好.什么牌子电脑包.电脑包牌子.最好的电脑包.电脑包什么牌子好排名.电脑包什么牌子好.电脑包什么品牌好――Nomadic智行者小尺寸大容量休闲电脑包。。...WR-08电脑包主包部分设有两个隔间,电脑包隔间中间还配有3块特殊的收纳袋,供用户收纳小部件,比如钱包、电话以及证件等贵重物品。在主包的另外一侧,设有两个中型收纳袋副包,可以用来防止移动电源、笔记本电源适配器等物件

问题二:我想买个双肩电脑背包,请问什么牌子的好? 双肩包可以考虑SWISSGEAR瑞士军刀 军刀包容量都很大,可以当笔记本包也可以当旅行包(放衣物)军刀包国内有厂家。这个品牌基本都是授权厂家去做了(国内厂出厂都有防伪标签,每个省不同)。所以可以说质量上是正品!基本价格都在100到200间!

问题三:双肩电脑包什么牌子的好 电脑包选择的时候:

看防水功能怎么样。

隔断的海绵能够缓冲保护电脑。

材质是否好,包括配件拉链质量怎么样。

如果考虑品牌的话,也要从这几方面考虑。

至于品牌,个人喜欢而已,可以参见电子商务平台的品牌。

问题四:双肩电脑包什么牌子最好? 也给您推荐一下选择的小技巧:

1,现在的网上背包品牌很多。只有买过才知道不同品牌质量差距不是一般的大。质量主要从做工体现出来。看做工。比如缝线是否细密,稍微用力拉看看有没有很明显的撕开痕迹。,

2,看细节。比如说拉链,一般来说,用YKK的比较有保障;

3,看设计。比如说侧边小兜的设计,如果你背着包手够这个小兜比较费劲的话,那肯定是他的设计有问题。或者是内兜里如果装笔记本,是否能装的下,有没有防震设计等等。

4,也可以通过和大品牌背包之间的比较来看出一点端倪。

“游月人”的背包全球第一背包品牌,是卡马箱包下的品牌,可以去官方看看,因此绝对是正品。价格也不贵,性价比最高了。瑞士的话,在国内是的中国威戈。或者看看CAT。

问题五:电脑包什么牌子好的啊 10分 一、款式已不仅仅是男式、女式,更多的中性包已陆续有推出。

二、尺寸10.6、12.1、13.3、14.1、15.2、15.4、17寸等包都已经面市;随着更多种尺寸的笔记本的推出,电脑包的厂商也在快速的推出相匹配的尺寸包;如今市面上一般还是以13-15寸的包为主。

三、材料(面料)有:各级别的弹道尼龙斜纹尼龙细文尼龙、强化多元脂布、锦纶、克维滋皮、真牛皮等.。

电脑包什么牌子好

1、中高端电脑包什么牌子好:瑞士军刀、LIOVO雷洛、金圣斯、森泰斯、Dewar的沃、瑞士军刀、FEGER/斐格、伦威保罗、泰格斯、托卡诺、泰伦斯、米莱恩、天盾、富力狮、优配等;中低端:

VIAVIAT(威尔维特)等;

2、电脑包什么牌子好OEM包:即各品牌笔记本自带的电脑包,如著名的IBM红点包、SONY包等(由泰格斯、森泰斯的品牌代工);

3、电脑包什么牌子好参差不齐的仿冒包,从款式,颜色LOGO、掉牌等方面都有仿冒,甚至商标都有仿的很像的。

一、款式已不仅仅是男式、女式,更多的中性包已陆续有推出。

二、尺寸10.6、12.1、13.3、14.1、15.2、15.4、17寸等包都已经面市;随着更多种尺寸的笔记本的推出,电脑包的厂商也在快速的推出相匹配的尺寸包;如今市面上一般还是以13-15寸的包为主。

三、材料(面料)有:各级别的弹道尼龙斜纹尼龙细文尼龙、强化多元脂布、锦纶、克维滋皮、真牛皮等.。

电脑做一些必要的保护是应该的。内胆包与电脑贴合的最为紧密,但其驾驶可以起到一定的保护作用,但对于吸收外部冲击方面,自然没有专业的电脑包更给力。而且由于一般其功能性最差,无法另外装其他东西,所以一般我们都还将另外带一款包包

问题六:哪个牌子的电脑包质量好? 我都是用原装的电脑包,没有另外买过,所以不是很了解哦,不过你可以参考下十大品牌的,现在很多行业都有十大品牌,十大品牌是这个行业里做得最好的牌子,你不妨到买购中国十大品牌网看下有没有电脑包十大品牌的信息,我平时一般都是到那了解品牌的信息的

问题七:我想买个双肩电脑背包,请问什么牌子的好? 泰格奴的

问题八:哪个品牌的电脑包好? 瑞士威戈真空防震电脑包,商务人士绝配最大可容纳14寸屏幕笔记本电脑,国际标准的产品内框,防震防撞性超强,可以更好的保护你的笔记本电脑的安全,延长使用寿...具体你可以登录它的官方网详细了解和选购。

问题九:什么牌子的电脑背包好 牌子固然能体现出面子来,质量和设计更为重要。电脑包重要的是能给电脑安全保护,首先是防震、防潮。所以有内固定带的、密封较好的笔记本电脑包自然更受欢迎。

另外就是内外袋布置,这就需要你斟酌平时都会随时带些什么东西,记录本、钢笔、上网卡、优盘、光盘、水杯等。

考虑舒适性,双肩背包比单肩背包好,宽背带比窄背带舒服。还有就是这就留意电脑包与后背接触位置透气性是不是更好,这避免你捂一身汗,电脑却黏黏的贴背上。

最后说牌子,我个人对品牌不太在意。不过如果某个的电脑包的牌子你熟悉,而且保证是正品,那就不要犹豫了。

问题十:电脑双肩背包什么牌子好? 10分 STM flight 淘宝有,不错 好背、耐用、重保护且多功能的iPad侧背包,那么STM的这款侧背袋会是你不错的选择。带点军风的外观设计,用耐磨、防泼水的高密度帆布。最外层的上盖用牢靠的大型活扣固定,而放置iPad的内袋则以加厚的防撞EVA 环绕,柔软毛呢内里打造,另外加上一层魔术贴的翻盖,为你的iPad提供多层次的加强型防护。这款侧背包小巧,但功能收纳能强,拥有数个收纳夹层,你可以完整收纳所有iPad周边随身物品。最前方的口袋拥有笔套与两个小夹层,并缝上一个活扣式钥匙环,很适合合放置一些需经常取出使用的物品;上方配置一个拉链夹袋,空间恰巧能收纳皮夹或iPhone等重要物品;背面也有一个文件夹层,可以放一些B5尺寸的小书本或文件,相当实用

有哪些适合装笔记本电脑、适合上下班通勤的平价大包推荐?

作为一个热衷买包的人士,家里有很多大大小小的包,今天就来推荐几款既实用百搭又超高性价比的大包包!

这个包是从得物购入的,150+。这种亮皮的托特包真的既休闲又小众,运动背、通勤背、出差背。容量大是必须的,内里也有口袋夹层,可以放一些贵重的东西。已经用了3年了,依然没有任何问题,非常耐磨。

Kangol这个包冬天背真的太合适了,色系非常适合秋冬的穿搭。包身是充棉的,既保温又防撞,侧边还有口袋可以放水杯,容量也是超大的。用了1年了,只有一个缺点肩带有点太窄了,背电脑的时候有点硌人。价格有点略贵300+,但是可以用上五六年。淘宝kangol官方旗舰店购入。

这是我朋友推荐的一款包,既可以单肩背显休闲,又可以手提显正式。材质是PU革的,磁吸式包口,里面必备拉链暗袋。但这个包体积挺大的,比较适合高个女生。淘宝(花满格旗舰店)150购入。

买这包没别的原因就是因为好看。是牛仔帆布包,有拉链可以关包,内里也有暗袋,背面还有大收纳袋,底部有硬托设计,装东西不易下坠。使用之后发现面料很软,非常厚实耐磨,很实用。上面还有一些小刺绣,超可爱的,淘宝(皮琦芭斯)69购入。

帆布包也是通勤的一把好手,自身很轻质量也是可以用1年左右的,平价好用还有股文艺氛围。个人建议可以先买米白色或者黑色,几乎是百搭款式,推荐一些淘宝店铺。

推荐了一些用过的包包,不知道能不能满足大家的需求呢!

0-1背包问题的多种解法代码(动态规划、贪心法、回溯法、分支限界法)

一.动态规划求解0-1背包问题

/************************************************************************/

/* 0-1背包问题:

/* 给定n种物品和一个背包

/* 物品i的重量为wi,其价值为vi

/* 背包的容量为c

/* 应如何选择装入背包的物品,使得装入背包中的物品

/* 的总价值最大?

/* 注:在选择装入背包的物品时,对物品i只有两种选择,

/* 即装入或不装入背包。不能将物品i装入多次,也

/* 不能只装入部分的物品i。

/*

/* 1. 0-1背包问题的形式化描述:

/* 给定c>0, wi>0, vi>0, 0<=i<=n,要求找到一个n元的

/* 0-1向量(x1, x2, ..., xn), 使得:

/* max sum_{i=1 to n} (vi*xi),且满足如下约束:

/* (1) sum_{i=1 to n} (wi*xi) <= c

/* (2) xi∈{0, 1}, 1<=i<=n

/*

/* 2. 0-1背包问题的求解

/* 0-1背包问题具有最优子结构性质和子问题重叠性质,适于

/* 用动态规划方法求解

/*

/* 2.1 最优子结构性质

/* 设(y1,y2,...,yn)是给定0-1背包问题的一个最优解,则必有

/* 结论,(y2,y3,...,yn)是如下子问题的一个最优解:

/* max sum_{i=2 to n} (vi*xi)

/* (1) sum_{i=2 to n} (wi*xi) <= c - w1*y1

/* (2) xi∈{0, 1}, 2<=i<=n

/* 因为如若不然,则该子问题存在一个最优解(z2,z3,...,zn),

/* 而(y2,y3,...,yn)不是其最优解。那么有:

/* sum_{i=2 to n} (vi*zi) > sum_{i=2 to n} (vi*yi)

/* 且,w1*y1 + sum_{i=2 to n} (wi*zi) <= c

/* 进一步有:

/* v1*y1 + sum_{i=2 to n} (vi*zi) > sum_{i=1 to n} (vi*yi)

/* w1*y1 + sum_{i=2 to n} (wi*zi) <= c

/* 这说明:(y1,z2,z3,...zn)是所给0-1背包问题的更优解,那么

/* 说明(y1,y2,...,yn)不是问题的最优解,与前提矛盾,所以最优

/* 子结构性质成立。

/*

/* 2.2 子问题重叠性质

/* 设所给0-1背包问题的子问题 P(i,j)为:

/* max sum_{k=i to n} (vk*xk)

/* (1) sum_{k=i to n} (wk*xk) <= j

/* (2) xk∈{0, 1}, i<=k<=n

/* 问题P(i,j)是背包容量为j、可选物品为i,i+1,...,n时的子问题

/* 设m(i,j)是子问题P(i,j)的最优值,即最大总价值。则根据最优

/* 子结构性质,可以建立m(i,j)的递归式:

/* a. 递归初始 m(n,j)

/* //背包容量为j、可选物品只有n,若背包容量j大于物品n的

/* //重量,则直接装入;否则无法装入。

/* m(n,j) = vn, j>=wn

/* m(n,j) = 0, 0<=j<wn

/* b. 递归式 m(i,j)

/* //背包容量为j、可选物品为i,i+1,...,n

/* //如果背包容量j<wi,则根本装不进物品i,所以有:

/* m(i,j) = m(i+1,j), 0<=j<wi

/* //如果j>=wi,则在不装物品i和装入物品i之间做出选择

/* 不装物品i的最优值:m(i+1,j)

/* 装入物品i的最优值:m(i+1, j-wi) + vi

/* 所以:

/* m(i,j) = max {m(i+1,j), m(i+1, j-wi) + vi}, j>=wi

/*

/************************************************************************/

#define max(a,b) (((a) > (b)) ? (a) : (b))

#define min(a,b) (((a) < (b)) ? (a) : (b))

template <typename 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 (j=w[n]; j<=c; j++) {

m[n][j] = v[n];

}

//i从2到n-1,分别对j>=wi和0<=j<wi即使m(i,j)

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 (j=w[i]; j<=c; j++) {

m[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 <typename 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;

}

int main(int argc, char* argv[])

{

int n = 5;

int w[6] = {-1, 2, 2, 6, 5, 4};

int v[6] = {-1, 6, 3, 5, 4, 6};

int c = 10;

int **ppm = new int*[n+1];

for (int i=0; i<n+1; i++) {

ppm[i] = new int[c+1];

}

int x[6];

Knapsack<int>(v, w, c, n, ppm);

TraceBack<int>(ppm, w, c, n, x);

return 0;

}

二.贪心算法求解0-1背包问题

1.贪心法的基本思路:

——从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。

该算法存在问题:

1).不能保证求得的最后解是最佳的;

2).不能用来求最大或最小解问题;

3).只能求满足某些约束条件的可行解的范围。

实现该算法的过程:

从问题的某一初始解出发;

while 能朝给定总目标前进一步 do

求出可行解的一个解元素;

由所有解元素组合成问题的一个可行解;

2.例题分析

1).[背包问题]有一个背包,背包容量是M=150。有7个物品,物品可以分割成任意大小。

要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

物品 A B C D E F G

重量 35 30 60 50 40 10 25

价值 10 40 30 50 35 40 30

分析:

目标函数: ∑pi最大

约束条件是装入的物品总重量不超过背包容量:∑wi<=M( M=150)

(1)根据贪心的策略,每次挑选价值最大的物品装入背包,得到的结果是否最优?

(2)每次挑选所占空间最小的物品装入是否能得到最优解?

(3)每次选取单位容量价值最大的物品,成为解本题的策略。

<程序代码:>(环境:c++)

#include<iostream.h>

#define max 100 //最多物品数

void sort (int n,float a[max],float b[max]) //按价值密度排序

{

int j,h,k;

float t1,t2,t3,c[max];

for(k=1;k<=n;k++)

c[k]=a[k]/b[k];

for(h=1;h<n;h++)

for(j=1;j<=n-h;j++)

if(c[j]<c[j+1])

{t1=a[j];a[j]=a[j+1];a[j+1]=t1;

t2=b[j];b[j]=b[j+1];b[j+1]=t2;

t3=c[j];c[j]=c[j+1];c[j+1]=t3;

}

}

void knapsack(int n,float limitw,float v[max],float w[max],int x[max])

{float c1; //c1为背包剩余可装载重量

int i;

sort(n,v,w); //物品按价值密度排序

c1=limitw;

for(i=1;i<=n;i++)

{

if(w[i]>c1)break;

x[i]=1; //x[i]为1时,物品i在解中

c1=c1-w[i];

}

}

void main()

{int n,i,x[max];

float v[max],w[max],totalv=0,totalw=0,limitw;

cout<<"请输入n和limitw:";

cin>>n >>limitw;

for(i=1;i<=n;i++)

x[i]=0; //物品选择情况表初始化为0

cout<<"请依次输入物品的价值:"<<endl;

for(i=1;i<=n;i++)

cin>>v[i];

cout<<endl;

cout<<"请依次输入物品的重量:"<<endl;

for(i=1;i<=n;i++)

cin>>w[i];

cout<<endl;

knapsack (n,limitw,v,w,x);

cout<<"the selection is:";

for(i=1;i<=n;i++)

{

cout<<x[i];

if(x[i]==1)

totalw=totalw+w[i];

}

cout<<endl;

cout<<"背包的总重量为:"<<totalw<<endl; //背包所装载总重量

cout<<"背包的总价值为:"<<totalv<<endl; //背包的总价值

}

三.回溯算法求解0-1背包问题

1.0-l背包问题是子集选取问题。

一般情况下,0-1背包问题是NP难题。0-1背包

问题的解空间可用子集树表示。解0-1背包问题的回溯法与装载问题的回溯法十分类

似。在搜索解空间树时,只要其左儿子结点是一个可行结点,搜索就进入其左子树。当

右子树有可能包含最优解时才进入右子树搜索。否则将右子树剪去。设r是当前剩余

物品价值总和;cp是当前价值;bestp是当前最优价值。当cp+r≤bestp时,可剪去右

子树。计算右子树中解的上界的更好方法是将剩余物品依其单位重量价值排序,然后

依次装入物品,直至装不下时,再装入该物品的一部分而装满背包。由此得到的价值是

右子树中解的上界。

2.解决办法思路:

为了便于计算上界,可先将物品依其单位重量价值从大到小排序,此后只要顺序考

察各物品即可。在实现时,由bound计算当前结点处的上界。在搜索解空间树时,只要其左儿子节点是一个可行结点,搜索就进入左子树,在右子树中有可能包含最优解是才进入右子树搜索。否则将右子树剪去。

回溯法是一个既带有系统性又带有跳跃性的的搜索算法。它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。如果肯定不包含,则跳过对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。否则,进入该子树,继续按深度优先的策略进行搜索。回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。而回溯法在用来求问题的任一解时,只要搜索到问题的一个解就可以结束。这种以深度优先的方式系统地搜索问题的解的算法称为回溯法,它适用于解一些组合数较大的问题。

2.算法框架:

a.问题的解空间:应用回溯法解问题时,首先应明确定义问题的解空间。问题的解空间应到少包含问题的一个(最优)解。

b.回溯法的基本思想:确定了解空间的组织结构后,回溯法就从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。这个开始结点就成为一个活结点,同时也成为当前的扩展结点。在当前的扩展结点处,搜索向纵深方向移至一个新结点。这个新结点就成为一个新的活结点,并成为当前扩展结点。如果在当前的扩展结点处不能再向纵深方向移动,则当前扩展结点就成为死结点。换句话说,这个结点不再是一个活结点。此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。回溯法即以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已没有活结点时为止。

3.运用回溯法解题通常包含以下三个步骤:

a.针对所给问题,定义问题的解空间;

b.确定易于搜索的解空间结构;

c.以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索;

#include<iostream>

using namespace std;

class Knap

{

friend int Knapsack(int p[],int w[],int c,int n );

public:

void print()

{

for(int m=1;m<=n;m++)

{

cout<<bestx[m]<<" ";

}

cout<<endl;

};

private:

int Bound(int i);

void Backtrack(int i);

int c;//背包容量

int n; //物品数

int *w;//物品重量数组

int *p;//物品价值数组

int cw;//当前重量

int cp;//当前价值

int bestp;//当前最优值

int *bestx;//当前最优解

int *x;//当前解

};

int Knap::Bound(int i)

{

//计算上界

int cleft=c-cw;//剩余容量

int b=cp;

//以物品单位重量价值递减序装入物品

while(i<=n&&w[i]<=cleft)

{

cleft-=w[i];

b+=p[i];

i++;

}

//装满背包

if(i<=n)

b+=p[i]/w[i]*cleft;

return b;

}

void Knap::Backtrack(int i)

{

if(i>n)

{

if(bestp<cp)

{

for(int j=1;j<=n;j++)

bestx[j]=x[j];

bestp=cp;

}

return;

}

if(cw+w[i]<=c) //搜索左子树

{

x[i]=1;

cw+=w[i];

cp+=p[i];

Backtrack(i+1);

cw-=w[i];

cp-=p[i];

}

if(Bound(i+1)>bestp)//搜索右子树

{

x[i]=0;

Backtrack(i+1);

}

}

class Object

{

friend int Knapsack(int p[],int w[],int c,int n);

public:

int operator<=(Object a)const

{

return (d>=a.d);

}

private:

int ID;

float d;

};

int Knapsack(int p[],int w[],int c,int n)

{

//为Knap::Backtrack初始化

int W=0;

int P=0;

int i=1;

Object *Q=new Object[n];

for(i=1;i<=n;i++)

{

Q[i-1].ID=i;

Q[i-1].d=1.0*p[i]/w[i];

P+=p[i];

W+=w[i];

}

if(W<=c)

return P;//装入所有物品

//依物品单位重量排序

float f;

for( i=0;i<n;i++)

for(int j=i;j<n;j++)

{

if(Q[i].d<Q[j].d)

{

f=Q[i].d;

Q[i].d=Q[j].d;

Q[j].d=f;

}

}

Knap K;

K.p = new int[n+1];

K.w = new int[n+1];

K.x = new int[n+1];

K.bestx = new int[n+1];

K.x[0]=0;

K.bestx[0]=0;

for( i=1;i<=n;i++)

{

K.p[i]=p[Q[i-1].ID];

K.w[i]=w[Q[i-1].ID];

}

K.cp=0;

K.cw=0;

K.c=c;

K.n=n;

K.bestp=0;

//回溯搜索

K.Backtrack(1);

K.print();

delete [] Q;

delete [] K.w;

delete [] K.p;

return K.bestp;

}

void main()

{

int *p;

int *w;

int c=0;

int n=0;

int i=0;

char k;

cout<<"0-1背包问题——回溯法 "<<endl;

cout<<" by zbqplayer "<<endl;

while(k)

{

cout<<"请输入背包容量(c):"<<endl;

cin>>c;

cout<<"请输入物品的个数(n):"<<endl;

cin>>n;

p=new int[n+1];

w=new int[n+1];

p[0]=0;

w[0]=0;

cout<<"请输入物品的价值(p):"<<endl;

for(i=1;i<=n;i++)

cin>>p[i];

cout<<"请输入物品的重量(w):"<<endl;

for(i=1;i<=n;i++)

cin>>w[i];

cout<<"最优解为(bestx):"<<endl;

cout<<"最优值为(bestp):"<<endl;

cout<<Knapsack(p,w,c,n)<<endl;

cout<<"[s] 重新开始"<<endl;

cout<<"[q] 退出"<<endl;

cin>>k;

}

四.分支限界法求解0-1背包问题

1.问题描述:已知有N个物品和一个可以容纳M重量的背包,每种物品I的重量为WEIGHT,一个只能全放入或者不放入,求解如何放入物品,可以使背包里的物品的总效益最大。

2.设计思想与分析:对物品的选取与否构成一棵解树,左子树表示不装入,右表示装入,通过检索问题的解树得出最优解,并用结点上界杀死不符合要求的结点。

#include <iostream.h>

struct good

{

int weight;

int benefit;

int flag;//是否可以装入标记

};

int number=0;//物品数量

int upbound=0;

int curp=0, curw=0;//当前效益值与重量

int maxweight=0;

good *bag=NULL;

void Init_good()

{

bag=new good [number];

for(int i=0; i<number; i++)

{

cout<<"请输入第件"<<i+1<<"物品的重量:";

cin>>bag[i].weight;

cout<<"请输入第件"<<i+1<<"物品的效益:";

cin>>bag[i].benefit;

bag[i].flag=0;//初始标志为不装入背包

cout<<endl;

}

}

int getbound(int num, int *bound_u)//返回本结点的c限界和u限界

{

for(int w=curw, p=curp; num<number && (w+bag[num].weight)<=maxweight; num++)

{

w=w+bag[num].weight;

p=w+bag[num].benefit;

}

*bound_u=p+bag[num].benefit;

return ( p+bag[num].benefit*((maxweight-w)/bag[num].weight) );

}

void LCbag()

{

int bound_u=0, bound_c=0;//当前结点的c限界和u限界

for(int i=0; i<number; i++)//逐层遍历解树决定是否装入各个物品

{

if( ( bound_c=getbound(i+1, &bound_u) )>upbound )//遍历左子树

upbound=bound_u;//更改已有u限界,不更改标志

if( getbound(i, &bound_u)>bound_c )//遍历右子树

//若装入,判断右子树的c限界是否大于左子树根的c限界,是则装入

{

upbound=bound_u;//更改已有u限界

curp=curp+bag[i].benefit;

curw=curw+bag[i].weight;//从已有重量和效益加上新物品

bag[i].flag=1;//标记为装入

}

}

}

void Display()

{

cout<<"可以放入背包的物品的编号为:";

for(int i=0; i<number; i++)

if(bag[i].flag>0)

cout<<i+1<<" ";

cout<<endl;

delete []bag;

}