动态规划解背包问题方法
动态规划与回溯法解决0-1背包问题

0-1背包动态规划解决问题一、问题描述:有n个物品,它们有各自的重量和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?二、总体思路:根据动态规划解题步骤(问题抽象化、建立模型、寻找约束条件、判断是否满足最优性原理、找大问题与小问题的递推关系式、填表、寻找解组成)找出01背包问题的最优解以及解组成,然后编写代码实现。
原理:动态规划与分治法类似,都是把大问题拆分成小问题,通过寻找大问题与小问题的递推关系,解决一个个小问题,最终达到解决原问题的效果。
但不同的是,分治法在子问题和子子问题等上被重复计算了很多次,而动态规划则具有记忆性,通过填写表把所有已经解决的子问题答案纪录下来,在新问题里需要用到的子问题可以直接提取,避免了重复计算,从而节约了时间,所以在问题满足最优性原理之后,用动态规划解决问题的核心就在于填表,表填写完毕,最优解也就找到。
过程:a) 把背包问题抽象化(X1,X2,…,Xn,其中 Xi 取0或1,表示第i 个物品选或不选),V i表示第i 个物品的价值,W i表示第i 个物品的体积(重量);b) 建立模型,即求max(V1X1+V2X2+…+VnXn);c) 约束条件,W1X1+W2X2+…+WnXn<capacity;d) 定义V(i,j):当前背包容量j,前i 个物品最佳组合对应的价值;e) 最优性原理是动态规划的基础,最优性原理是指“多阶段决策过程的最优决策序列具有这样的性质:不论初始状态和初始决策如何,对于前面决策所造成的某一状态而言,其后各阶段的决策序列必须构成最优策略”。
判断该问题是否满足最优性原理,采用反证法证明:假设(X1,X2,…,Xn)是01背包问题的最优解,则有(X2,X3,…,Xn)是其子问题的最优解,假设(Y2,Y3,…,Yn)是上述问题的子问题最优解,则理应有(V2Y2+V3Y3+…+V n Yn)+V1X1 > (V2X2+V3X3+…+VnXn)+V1X1;而(V2X2+V3X3+…+VnXn)+V1X1=(V1X1+V2X2+…+VnXn),则有(V2Y2+V3Y3+…+VnYn)+V1X1 > (V1X1+V2X2+…+VnXn);该式子说明(X1,Y2,Y3,…,Yn)才是该01背包问题的最优解,这与最开始的假设(X1,X2,…,Xn)是01背包问题的最优解相矛盾,故01背包问题满足最优性原理;f) 寻找递推关系式,面对当前商品有两种可能性:第一,包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,即V(i,j)=V(i-1,j);第二,还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个,即V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i) }其中V(i-1,j)表示不装,V(i-1,j-w(i))+v(i) 表示装了第i个商品,背包容量减少w(i)但价值增加了v(i);由此可以得出递推关系式:1) j<w(i) V(i,j)=V(i-1,j)2) j>=w(i) V(i,j)=max{ V(i-1,j),V(i-1,j-w(i))+v(i) }number=4,capacity=7四、构造最优解:最优解的构造可根据C列的数据来构造最优解,构造时从第一个物品开始。
《信息学奥赛一本通》:第9章 第2节 动态规划背包问题(C++版)

【参考程序】
#include<cstdio> using namespace std;
const int maxm = 201, maxn = 31;
int m, n;
int w[maxn], c[maxn];
int f[maxn][maxm];
int main()
{
scanf("%d%d",&m, &n);
for (int i=1; i <= n; i++)
//设f(v)表示重量不超过v公斤的最大价值
for (int v = m; v >= w[i]; v--)
if (f[v-w[i]]+c[i]>f[v])
f[v] = f[v-w[i]]+c[i];
printf("%d",f[m]);
// f(m)为最优解
【例9-12】、完全背包问题 【问题描述】
设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限 的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品 可以多次选取),使其重量的和小于等于M,而价值的和为最大。
【输入格式】
第一行:两个整数,M(背包容量,M<=200)和N(物品数量,N<=30); 第2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。 【输出格式】
第九章 动态规划
第二节 背包问题
第二节 背包问题
一、01背包问题 问题:
有N件物品和一个容量为V的背包。第i件物品的费用(即体积,下同)是w[i], 价值是c[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量, 且价值总和最大。 基本思路:
动态规划——01背包问题

动态规划——01背包问题⼀、最基础的动态规划之⼀01背包问题是动态规划中最基础的问题之⼀,它的解法完美地体现了动态规划的思想和性质。
01背包问题最常见的问题形式是:给定n件物品的体积和价值,将他们尽可能地放⼊⼀个体积固定的背包,最⼤的价值可以是多少。
我们可以⽤费⽤c和价值v来描述⼀件物品,再设允许的最⼤花费为w。
只要n稍⼤,我们就不可能通过搜索来遍查所有组合的可能。
运⽤动态规划的思想,我们把原来的问题拆分为⼦问题,⼦问题再进⼀步拆分直⾄不可再分(初始值),随后从初始值开始,尽可能地求取每⼀个⼦问题的最优解,最终就能求得原问题的解。
由于不同的问题可能有相同的⼦问题,⼦问题存在⼤量重叠,我们需要额外的空间来存储已经求得的⼦问题的最优解。
这样,可以⼤幅度地降低时间复杂度。
有了这样的思想,我们来看01背包问题可以怎样拆分成⼦问题:要求解的问题是:在n件物品中最⼤花费为w能得到的最⼤价值。
显然,对于0 <= i <= n,0 <= j <= w,在前i件物品中最⼤花费为j能得到的最⼤价值。
可以使⽤数组dp[n + 1][w + 1]来存储所有的⼦问题,dp[i][j]就代表从前i件物品中选出总花费不超过j时的最⼤价值。
可知dp[0][j]值⼀定为零。
那么,该怎么递推求取所有⼦问题的解呢。
显⽽易见,要考虑在前i件物品中拿取,⾸先要考虑前i - 1件物品中拿取的最优情况。
当我们从第i - 1件物品递推到第i件时,我们就要考虑这件物品是拿,还是不拿,怎样收益最⼤。
①:⾸先,如果j < c[i],那第i件物品是⽆论如何拿不了的,dp[i][j] = dp[i - 1][j];②:如果可以拿,那就要考虑拿了之后收益是否更⼤。
拿这件物品需要花费c[i],除去这c[i]的⼦问题应该是dp[i - 1][j - c[i]],这时,就要⽐较dp[i - 1][j]和dp[i - 1][j - c[i]] + v[i],得出最优⽅案。
动态规划——背包问题python实现(01背包、完全背包、多重背包)

动态规划——背包问题python实现(01背包、完全背包、多重背包)参考:⽬录描述:有N件物品和⼀个容量为V的背包。
第i件物品的体积是vi,价值是wi。
求解将哪些物品装⼊背包,可使这些物品的总体积不超过背包流量,且总价值最⼤。
⼆维动态规划f[i][j] 表⽰只看前i个物品,总体积是j的情况下,总价值最⼤是多少。
result = max(f[n][0~V]) f[i][j]:不选第i个物品:f[i][j] = f[i-1][j];选第i个物品:f[i][j] = f[i-1][j-v[i]] + w[i](v[i]是第i个物品的体积)两者之间取最⼤。
初始化:f[0][0] = 0 (啥都不选的情况,不管容量是多少,都是0?)代码如下:n, v = map(int, input().split())goods = []for i in range(n):goods.append([int(i) for i in input().split()])# 初始化,先全部赋值为0,这样⾄少体积为0或者不选任何物品的时候是满⾜要求dp = [[0 for i in range(v+1)] for j in range(n+1)]for i in range(1, n+1):for j in range(1,v+1):dp[i][j] = dp[i-1][j] # 第i个物品不选if j>=goods[i-1][0]:# 判断背包容量是不是⼤于第i件物品的体积# 在选和不选的情况中选出最⼤值dp[i][j] = max(dp[i][j], dp[i-1][j-goods[i-1][0]]+goods[i-1][1])print(dp[-1][-1])⼀维动态优化从上⾯⼆维的情况来看,f[i] 只与f[i-1]相关,因此只⽤使⽤⼀个⼀维数组[0~v]来存储前⼀个状态。
那么如何来实现呢?第⼀个问题:状态转移假设dp数组存储了上⼀个状态,那么应该有:dp[i] = max(dp[i] , dp[i-v[i]]+w[i])max函数⾥⾯的dp[i]代表的是上⼀个状态的值。
背包问题python解法

背包问题python解法背包问题是一类经典的组合优化问题,其目标是在给定一组物品和一个背包的容量限制下,找到最佳的装法,使得背包中物品的总价值最大化。
在这篇文章中,我们将介绍一种使用Python编程语言解决背包问题的方法。
我们将使用动态规划技术来解决该问题,这是一种常用的解法。
动态规划解法背包问题的特点是将问题划分为子问题,并使用递推关系来解决整个问题。
我们首先定义一个二维数组dp,其中dp[i][j]表示在前i个物品中,背包容量为j时所能获得的最大价值。
接下来,我们使用递推公式来计算dp数组的值。
假设第i个物品的重量为weight[i],价值为value[i],我们有以下递推关系:dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i])该递推关系表示,我们可以选择将第i个物品放入背包中,也可以选择不放入背包中。
如果选择放入,背包的容量将减少weight[i],与此同时,背包的价值将增加value[i]。
因此,我们需要比较不放入该物品时,背包中的价值与放入该物品后背包中的价值,选择其中较大的值作为最优解。
最后,我们通过遍历整个dp数组,找到最大的背包价值。
最大背包价值即为背包问题的最优解。
下面是采用Python语言实现背包问题解法的代码:```pythondef knapsack(weight, value, capacity):n = len(weight)dp = [[0] * (capacity + 1) for _ in range(n + 1)]for i in range(1, n + 1):for j in range(1, capacity + 1):if weight[i - 1] <= j:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i - 1]] + value[i - 1])else:dp[i][j] = dp[i - 1][j]return dp[n][capacity]```在上述代码中,我们传入了三个参数:weight表示物品的重量列表,value表示物品的价值列表,capacity表示背包的容量。
(完整版)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背包问题【精选】

一、实验内容:分别用蛮力法、动态规划法、回溯法和分支限界法求解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背包问题的时间复杂度为:。
动态规划问题常见解法

动态规划问题常见解法
动态规划是一种高效解决优化问题的方法。
它通常用于涉及最
优化问题和最短路径的计算中。
下面是一些常见的动态规划问题解法:
1. 背包问题
背包问题是动态规划中的经典问题之一。
其目标是在给定的背
包容量下,选择一些物品放入背包中,使得物品总价值最大。
解决
这个问题的常见方法是使用动态规划的思想,定义一个二维数组来
记录每个物品放入背包时的最大价值,然后逐步计算出最终的结果。
2. 最长公共子序列问题
最长公共子序列问题是寻找两个字符串中最长的公共子序列的
问题。
解决这个问题的常见方法是使用动态规划的思想,定义一个
二维数组来记录两个字符串中每个位置的最长公共子序列的长度。
然后通过递推关系来计算出最终的结果。
3. 矩阵链乘法问题
矩阵链乘法问题是计算一系列矩阵相乘的最佳顺序的问题。
解
决这个问题的常见方法是使用动态规划的思想,定义一个二维数组
来记录每个矩阵相乘时的最小乘法次数,然后逐步计算出最终的结果。
4. 最长递增子序列问题
最长递增子序列问题是寻找一个序列中最长的递增子序列的问题。
解决这个问题的常见方法是使用动态规划的思想,定义一个一
维数组来记录每个位置处的最长递增子序列的长度,然后通过递推
关系来计算出最终的结果。
以上是一些常见的动态规划问题解法。
通过灵活运用这些方法,我们可以更高效地解决优化问题和最短路径计算等相关任务。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
动态规划是运筹学的一个分支,是求解决策过程最优 化的数学方法。 20世纪50年代,Richard Bellman等人提出了解决多阶 段决策问题的“最优性原理”,并创建了最优化问题 的一种新的求解方法--动态规划(Dynamic programming)。 “Programming”是计划和规划的意思,不是代表计 算机中的编程。
4
6
m[1][10]≠m[2][10]x[1]=1 (装入物品1) m[2][10-w1]=m[2][8] ≠m[3][8] x[2]=1 (装入物品2) m[3][8-w2]=m[3][6] =m[4][6] x[3]=0 (未装入物品3) m[4][6] = m[5][6] x[4]=0 (未装入物品4) m[5][6] ≠0 x[5]=1(装入物品5) 最优解为: (1,1,0,0,1),最优值为15
i i
C
w1 y1 wi zi C
i 2
这说明(z1,z2,…,zn)是所给问题的更优解,从而(y1 ,y2,…,yn)不是最优解,此为矛 盾。
7
递归关系
设所给0-1背包问题的子问题
max vk xk
k i
n wk xk j k i xk {0,1}, i k n
Wi i 2 1
0 0
1 0
2 6
3 6
4 9
5 9
6 12
7 12
8 15
9 15
10 15
Vi 6 3 5 4 6
2
6 5 4
2
3 4 5
0
0 0 0
0
0 0 0
3
0 0 0
3
0 0 0
6
6 6 6
6
6 6 6
9
6 6 6
9
6 6 6
9
6 6 6
10
10 10 6
11
11 10 6
求最优解
Wi i 2 1
Wi i 2 1 2 6 5 4 2 3 401来自234
5
6
7
8
9
10
Vi 6 3 5
0
0
0
0
0
0
0
0
6
6
6
6
6
6
6
6
6
6
10
6
10 4
6 6
5
最后,如果w1>C,则w1不放入,m[1,c]=m[2,c] 否则,从放与不放的最大值中选择最优值。 因为c=10>w1,所以, m[1,10]=max{m[2,10],m[2,c-w1]+v1} =max{11,m[2,8]+6}=max{11,15}=15 依此计算m[1,0..9]。
2 6 5 4 2 3 4 5 0 0 0 0 0 0 1 0 0 0 0 0 2 6 3 0 0 0 3 6 3 0 0 0 4 9 6 6 6 6 5 9 6 6 6 6 6 12 9 6 6 6 7 12 9 6 6 6 8 15 9 6 6 6 9 15 10 10 10 6 10 V i 15 11 11 10 6 6 3 5
6
反证法证明
否则,设(z2,z3,…,zn)是上述问题的一个最优解,而(y2,…,yn)不是它的最优解。 由此可知
v z v y , 且w y w z
i 2 i i
n
n
n
v1 y1 vi zi vi yi 因此,
i 2 n i 1
i 2 n
i
i
1 1
n
i 2
2
但是经分解得到的子问题往往不是互相独立的。不同 子问题的数目常常只有多项式量级。在用分治法求解 时,有些子问题被重复计算了许多次,以至于最后解决 原问题需要耗费指数时间。
T(n)
=
n
n/2
n/2
n/2
n/2
T(n/4)
T(n/4)
T(n/4)
T(n/4)
T(n/4) T(n/4) T(n/4) T(n/4) T(n/4) T(n/4)
Wi i 2 1 2 6 5 4 2 3 4 5
0
1
2
3
4
5
6
7
8
9
10 V i 6
3
5 0 0 0 0 6 6 6 6 6 6 6 4 6
再分析物品4,确定m[4,0..10]这11个元素的值。W[4]=5 j<w[4]:不能放入物品4,m[4,j]=m[5,j] j ≥ w[4]:对物品4要么放入,要么不放入(选择标准应依据 总价值),选总价值最大的。 不放:m[i,j]=m[i+1,j],即m[4,5]=m[5,5]=6 放入:m[i,j]=m[i+1,j-w4]+v4,即m[4,5]=m[5,0]+4=4
n
的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品 为i,i+1,…,n时0-1背包问题的最优值。
8
递归关系
不放入第i个物品,此 时背包中的最大价值 为
由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的 递归式如下。
j wi max{m(i 1, j ), m(i 1, j wi ) vi } m(i, j ) 0 j wi m(i 1, j )
设数组m[6][11] m[i][j]:表示可选物品为i,i+1,…,n背包容量为j(总重量)时背包 中所放物品的最大价值。
Wi i 2 1 0 1 2 3 4 5 6 7 8 9 10 Vi 6 3 5 4 6
2
6 5 4
2
3 4 5
首先,背包为空,先对物品n的放入背包的情况分析:即在 总重量为0~10时,如何放置物品n,使总价值最大。此时需 要确定m[5,0..10]11个元素的值。 w[5]=4,当背包容量j<w[5]时,物品5是不能放入的, m[5,j]=0;当j≥w[5]时,放入物品5价值最大,m[5,j]=v[5]
5
最优子结构性质
设(y1,y2,…,yn)是所给问题的一个最优 解,则(y2,…,yn)是下面相应子问题的一个最优 n 解: max vi xi i 2 说明: 一个n阶的问题, n w i x i C w 1y 1 可以由n-1阶的问 i 2 1}, 2 i n 题得到 x i {0,
max vi xi
i 1 n
n wi xi C i 1 xi {0,1},1 i n
4
0-1背包问题的应用
0-1背包问题是一类经典的组合优化问题 对0-1背包问题的研究可以广泛运用于资源分 配、投资决策、货物装载等方面。
1一辆货车有固定的载重量C,有n种货物,每种 货物i的重量和价格是(wi,vi),运输哪些货物有最 大的收益? 2 一个计算机有内存C,有n个程序,分别耗费内 存及其所交费用是(wi,vi),调度哪些程序使得 费用最大?
1
1
算法总体思想
• 动态规划算法与分治法类似,其基本思想也是 将待求解问题分解成若干个子问题
T(n)
n/2
=
n/2
n
n/2 n/2
T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n/4) T(n/4)T(n/4)T(n/4)T(n
T(n/4)
3
实例:0-1背包问题
给定n种物品和一背包。物品i的重量是wi,其价值为vi,背 包的容量为C。问应如何选择装入背包的物品,使得装入背 包中物品的总价值最大?
特点:每种物品仅有一件,可以选择放或不放。
输入:C>0, wi>0, vi>0, 1≤i≤n 输出:(x1, x2, …, xn), xi∈{0, 1}, 满足
j wn v n m(n, j ) 0 0 j wn
选择最后一个物品的情况
放入第i个物品,使剩余 物品(i+1,…,n)的最 大容量变为j-wi,此时背 包中的最大价值为
9
例:物品数量n=5,w[n]={2,2,6,5,4}, v[n]={6,3,5,4,6},背包总重量c=10