算法合集之《浅谈几类背包题》
理学背包问题详解

0 1 2 3 4 5 6 7 8 9 10
000000000000
x1=1
w1=2 v1=6 1 0 0 6 6 6 6 6 6 6 6 6
x2=1
w2=2 v2=3 2 0 0 6 6 9 9 9 9 9 9 9
x3=0
w3=6 v3=5 3 0 0 6 6 9 9 9 9 11 11 14
可用动态规划算法求解。
3
其他类型背包问题
完全背包问题(0/1):
有N种物品和一个容量为V的背包,每种物品都有 无限件可用。第i种物品的费用是c[i],价值是w[i]。 求解将哪些物品装入背包可使这些物品的费用总和 不超过背包容量,且价值总和最大。
多重背包问题
有N种物品和一个容量为V的背包。第i种物品最多 有n[i]件可用,每件费用是c[i],价值是w[i]。求解 将哪些物品装入背包可使这些物品的费用总和不超 过背包容量,且价值总和最大。
{// 计算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;
}
11
算法改进
由m(i,j)的递归式容易证明,在一般情况下,对每一个确定的 i(1≤i≤n),函数m(i,j)是关于变量j的阶梯状单调不减函数。跳跃 点是这一类函数的描述特征。在一般情况下,函数m(i,j)由其 全部跳跃点唯一确定。如图所示。
(7,7)
(6,6) (4,5)
(4,5)(6,6)
(0,
0)
(2,
(3,2) 1)
各种类型的背包问题

各种类型的背包问题P01: 01背包问题 题⽬ 有N件物品和⼀个容量为V的背包。
第i件物品的费⽤是c,价值是w。
求解将哪些物品装⼊背包可使这些物品的费⽤总和不超过背包容量,且价值总和最⼤。
基本思路 这是最基础的背包问题,特点是:每种物品仅有⼀件,可以选择放或不放。
⽤⼦问题定义状态:即f[v]表⽰前i件物品恰放⼊⼀个容量为v的背包可以获得的最⼤价值。
则其状态转移⽅程便是:f[v]=max{f[v],f[v-c]+w}。
这个⽅程⾮常重要,基本上所有跟背包相关的问题的⽅程都是由它衍⽣出来的。
所以有必要将它详细解释⼀下:“将前i件物品放⼊容量为v的背包中”这个⼦问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为⼀个只牵扯前i-1件物品的问题。
如果不放第i件物品,那么问题就转化为“前i-1件物品放⼊容量为v的背包中”;如果放第i件物品,那么问题就转化为“前i-1件物品放⼊剩下的容量为v-c的背包中”,此时能获得的最⼤价值就是f [v-c]再加上通过放⼊第i件物品获得的价值w。
注意f[v]有意义当且仅当存在⼀个前i件物品的⼦集,其费⽤总和为v。
所以按照这个⽅程递推完毕后,最终的答案并不⼀定是f[N] [V],⽽是f[N][0..V]的最⼤值。
如果将状态的定义中的“恰”字去掉,在转移⽅程中就要再加⼊⼀项f[v-1],这样就可以保证f[N] [V]就是最后的答案。
⾄于为什么这样就可以,由你⾃⼰来体会了。
优化空间复杂度 以上⽅法的时间和空间复杂度均为O(N*V),其中时间复杂度基本已经不能再优化了,但空间复杂度却可以优化到O(V)。
先考虑上⾯讲的基本思路如何实现,肯定是有⼀个主循环i=1..N,每次算出来⼆维数组f[0..V]的所有值。
那么,如果只⽤⼀个数组f [0..V],能不能保证第i次循环结束后f[v]中表⽰的就是我们定义的状态f[v]呢?f[v]是由f[v]和f [v-c]两个⼦问题递推⽽来,能否保证在推f[v]时(也即在第i次主循环中推f[v]时)能够得到f[v]和f[v -c]的值呢?事实上,这要求在每次主循环中我们以v=V..0的顺序推f[v],这样才能保证推f[v]时f[v-c]保存的是状态f[v-c]的值。
背包问题全类型

背包问题全类型背包问题给定⼀组物品,每种物品都有⾃⼰的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最⾼。
背包问题⼤体都可以⽤上述⽅式进⾏描述,但在具体的问题上有了不同的限制条件,于是便有了各种类型的背包问题。
背包问题可基本分为0-1背包问题、部分背包问题、多重背包问题、完全背包问题四⼤类。
接下从四种问题的解决的核⼼算法可以把部分背包问题单独化为⼀类,其核⼼算法为贪⼼。
其余的三种背包问题都可以⽤动态规划解决。
造成部分背包问题与其他的背包问题最⼤不同的原因是其限定条件的不同,部分1. 部分背包问题限定条件:每件物品可以只选取⼀部分完整问题描述:有 n 件物品,第i件物品重 w[i],价值为 v[i],且每件物品可以进⾏分割,分割后的价值按取⾛重量占该物品总重量的⽐值计算。
在不超过最⼤承载量 C 的范围内,问最⼤可以取⾛的价值为多少?( 其中 i ∈ {1,2,3,···,n} )算法:贪⼼分析:根据本题的特殊性,我们可以任意地对某⼀部品进⾏分割,所以我们优先选择性价⽐⾼的物品,即单位重量下物品的价值。
解题代码//C++#include<cstdio>#include<algorithm>#include<iostream>using namespace std;struct bag { int w,v; //w表⽰重量 v表⽰价值 double p; //⽤来储存v/w 性价⽐}a[10005];bool cmp(bag x,bag y) { return x.p > y.p; //性价⽐⾼的物品排在前⾯}int main() {剩余 } } printf('%.2f\n', ans); //输出答案 return 0;}注意计算时注意数据类型在计算“性价⽐”的时候要注意,在C/C++等⼀部分语⾔中存在以下机制 int/int = int ,这样是⽆法计算出⼩数的,需要将其中任意⼀项浮点化即可。
背包问题的多种解法

一个最优解:w i X i Wi2w1X1nmaX v i X i 。
如果不是的话,设(y2,y3, , y n) 是这X i {0,1}( 2 i n) i2问题描述0/1 背包问题 :现有n种物品,对1<=i<=n ,已知第i种物品的重量为正整数 W i,价值为正整数 V i, 背包能承受的最大载重量为正整数W,现要求找出这n种物品的一个子集,使得子集中物品的总重量不超过 W 且总价值尽量大。
(注意:这里对每种物品或者全取或者一点都不取,不允许只取一部分)算法分析根据问题描述,可以将其转化为如下的约束条件和目标函数:n w i x i Wi 1i i(1)x i { 0,1}( 1 i n)nmax v i x i (2)i1于是,问题就归结为寻找一个满足约束条件( 1 ),并使目标函数式( 2 )达到最大的解向量X (x1, x2 ,x3, ......... , x n) 。
首先说明一下 0-1 背包问题拥有最优解。
假设(X i,X2,X3,……,Xn)是所给的问题的一个最优解,则(X2,X3,……,Xn)是下面问题的n n n个问题的一个最优解,则v i y i v i X i ,且w1X1 w i y i W 。
因此,i 2 i 2 i 2n n n物品1W2=3V2=12物品2W3=4V3=40物品3W4=5V4=25物品4V1X1 V i y i V1X1 V i V i X i,这说明(X i,y2,y3, ............................................................... ,y n)是所给的 0-1 背包问i 2 i 2 i 1题比(X i,X2,X3, ........................... , X n)更优的解,从而与假设矛盾。
穷举法:用穷举法解决0-1背包问题,需要考虑给定 n个物品集合的所有子集,找出所有可能的子集(总重量不超过背包重量的子集) ,计算每个子集的总重量,然后在他们中找到价值最大的子集。
背包问题四种不同算法的实现

交通大学数理与软件工程学院题目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、贪心算法的根本原理与分析贪心算法总是作出在当前看来是最好的选择,即贪心算法并不从整体最优解上加以考虑,它所作出的选择只是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,但对围相当广的许多问题它能产生整体最优解。
在一些情况下,即使贪心算法不能得到整体最优解,但其最终结果却是最优解的很好近似解。
贪心算法求解的问题一般具有两个重要性质:贪心选择性质和最优子构造性质。
背包问题

01背包问题:1.递归思想0- 1 背包问题如果采用递归算法来描述则非常清楚明白, 它的算法根本思想是假设用布尔函数knap( s, n) 表示n 件物品放入可容质量为s 的背包中是否有解( 当knap 函数的值为真时说明问题有解,其值为假时无解) . 我们可以通过输入s 和n 的值, 根据它们的值可分为以下几种情况讨论:( 1) 当s= 0时可知问题有解, 即函数knap( s, n) 的值为true; ( 2) 当s< 0 时这时不可能,所以函数值为false; ( 3) 当输入的s> 0 且n< 1 时即总物品的件数不足1, 这时函数值为false,只有s> 0 且n \1 时才符合实际情况,这时又分为两种情况: ( 1) 选择的一组物体中不包括Wn则knap( s, n) 的解就是knap( s, n- 1) 的解. ( 2) 选择的一组物体中包括Wn 则knap( s, n) 的解就是knap( s- Wn, n- 1) 的解. 这样一组Wn 的值就是问题的最佳解. 这样就将规模为n 的问题转化为规模为n- 1 的问题. 综上所述0- 1 背包问题的递归函数定义为:knap( s, n) =∕true, s= 0︳false, s< 0︳false, s> 0 且n< 1\knap( s, n- 1) 或knap( s- Wn, n- 1) , s> 0 且n>= 1采用此法求解0- 1 背包问题的时间复杂度为O( n) . 上述算法对于所有物品中的某几件恰能装满背包时能准确求出最佳解. 但一般情况是对于某一些物品无论怎么装都不能装满背包, 必须要按背包的最大容量来装. 如物品件数为4, 其质量分别为: 10, 2, 5, 4, 背包的容量为20, 则这四件物品无论怎么放都不能恰好装满背包, 但应能最大限度装, 即必须装下10, 5, 4 这三件物品, 这样就能得到最大质量19. 对于这种装不满的背包它的解决办法是这样的: 按所有物品的组合质量最大的方法装背包, 如果还装不满,则我们可以考虑剩余空间能否装下所有物品中最小的那件, 如果连最小的都装不下了则说明这样得到的解是最佳解, 问题解决. 这样我们必须先找出所有n 件物品中质量最小的那件( 它的质量为Min) , 但是为了问题的解决我们不能增加运算次数太多, 并且必须运用上述递归函数. 那么我们可通过修改s 的值即背包的容量, 从背包容量s 中减去k( 它的值是从0 到Min- 1 之间的一个整数值) , 再调用递归函数. 当k= 0 时即能装满背包, 其它值也能保证背包能最大限度装满, 这样所有问题都解决了.①例题一:简单背包问题Time Limit: 1000MS Memory Limit: 65535KBSubmissions: 2217 Accepted: 408Description设有一个背包可以放入的物品重量为S,现有n件物品,重量分别是w1,w2,w3,…wn。
背包问题解题方法总结

背包问题解题⽅法总结最近在⽜客刷题遇到好⼏道背包问题,索性这两天集中⽕⼒刷了⼀些这类的题。
这⾥总结⼀下0-1背包、完全背包和多重背包三种基本的背包问题的解题套路。
(均基于动态规划的思想)0-1背包题⽬:有 N 件物品和容量为 W 的背包。
第 i 件物品的重量为 w_i,价值为 v_i,求将不超过背包容量的物品装⼊背包能得到的最⼤价值。
特点,每件物品的数量只有⼀个,可以选择放或不放某件物品。
⽤dp[i][j]表⽰将前 i+1 件总重量不超过 j 的物品放⼊背包能获得的最⼤价值,则可以⽤以下的转移⽅程来表⽰这个过程:\[dp[i,j] = max(dp[i - 1, j], dp[i-1, j-w[i]] + v[i]) \]注意到dp数组第i⾏的值更新只跟 i-1 ⾏有关,因此可以通过滚动数组或者反向更新的⽅式优化⼀下空间复杂度,在动态规划解题的时候这是⼀种常⽤的空间复杂度优化⽅式。
优化后的代码如下:for(int i = 0; i < N; i++){// 注意到这⾥dp需要从后往前更新,避免更新前就把旧值覆盖// 从实际意义上来说,因为每件物品只有⼀个,从后向前更新保证了更新是在还没放⼊过当前物品的前提下进⾏的for(int j = W; j >= w[i]; j--){dp[j] = Math.max(dp[j], dp[j - w[i]] + v[i]);}}完全背包题⽬:有 N 种物品和容量为 W 的背包。
第 i 种物品的重量为 w_i,价值为 v_i,每种物品的数量⽆限。
求将不超过背包容量的物品装⼊背包能得到的最⼤价值。
特点:每种物品的数量⽆限多。
考虑到每种物品的数量⽆限。
⽤dp[j]表⽰在重量不超过 j 的情况下背包中物品可以达到的最⼤价值,则转移⽅程如下:\[dp[j]=max(dp[j], dp[j-w[i]]+v[i]) \]核⼼代码如下:for(int i = 0; i < N; i++){for(int j = w[i]; j <= W; j++){ // 这⾥和0-1背包不同dp[j] = Math.max(dp[j], dp[j - w[i]] + v[i]);}}注意内层for循环是从前向后更新dp数组的,这是唯⼀和上⾯的0-1背包问题区别的地⽅。
国家集训队2009论文集浅谈几类背包题

浅谈几类背包题浙江省温州中学徐持衡指导老师:舒春平2008年12月目录摘要 (3)关键字 (3)正文 (4)一、引言 (4)二、背包的基本变换 (5)①完全背包 (5)②多次背包 (5)③单调队列优化☆ (6)三、其他几类背包问题 (8)①树形依赖背包(获取学分)☆ (8)②PKU3093☆ (11)四、总结 (12)附录 (13)参考文献 (13)文中原题 (13)摘要背包问题作为一个经典问题在动态规划中是很基础的一个部分,然而以0-1背包问题为原题,衍生转变出的各类题目,可以说是千变万化,当然解法也各有不同,如此就有了继续探究的价值。
本文就4道背包变化的题做一些探讨研究,提出本人的一些做法,希望能起到抛砖引玉的作用。
关键字动态规划背包优化正文一、引言背包问题是运筹学中的一个经典的优化难题,是一个NP-完全问题,但其有着广泛的实际应用背景,是从生活中一个常见的问题出发展开的:一个背包,和很多件物品,要在背包中放一些物品,以达到一定的目标。
在信息学中,把所有的数据都量化处理后,得到这样的一个问题:0-1 背包问题:给定n 件物品和一个背包。
物品i的价值是W i,其体积为V i,背包的容量为C。
可以任意选择装入背包中的物品,求装入背包中物品的最大总价值。
在选择装入背包的物品时,对每件物品i ,要么装入背包,要么不装入背包。
不能将物品i 多次装入背包,也不能只装入部分物品i (分割物品i)。
因此,该问题称为0-1 背包问题。
用于求解0-1背包问题的方法主要有回溯算法、贪婪算法、遗传算法、禁忌搜索算法、模拟退火算法等。
在高中阶段,我们所谓的经典0-1背包问题,保证了所有量化后的数据均为正整数,即是一个特殊的整数规划问题,本文中如无特殊说明均以此为前提。
其经典的O(n*C)动规解法是:状态是在前i件物品中,选取若干件物品其体积总和不大于j,所能获得的最大价值为F i[j],当前的决策是第i件物品放或者不放,最终得到转移方程:F i[j] = F i-1[j] (V i>j>=0)F i[j] = max{ F i-1[j] , F i-1[j-V i]+W i } (C>=j>=V i)其中由于F i只与F i-1有关,可以用滚动数组来节省程序的空间复杂度。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
背包问题作为一个经典问题在动态规划中是很 基础的一个部分,然而以0-1背包问题为原题, 衍生转变出的各类题目,可以说是千变万化, 当然解法也各有不同,如此就有了继续探究的 价值.
引言 背包的基本变换 ①完全背包 ②多次背包 ③单调队列优化 其他几类背包问题 ①树形依赖背包(选课) ②PKU3093 总结
Max ( Fi[ k ] , Fs[ k-Vs ] + Ws ) → Fi[ k ]
11 END
对于每一个节点都需要更新一次,所以总效率 是O(n*C+n^2). 其中找子节点的可以用记边的方式来实现,总 效率O(n*C). O(n*C)
用这个算法,可以把《选课》这一类treedp题 优化到O(n*C),亦可以作为noip06《金明的预 算方案》的O(n*C) treedp解法.
比如可以把体积d+j*v都退化到d,也就是说用 F[i-1,j*v+d]- j*w来代替原来的价值进行比较大 小. 这样就可以用单调队列来优化了,对于每件物 品的转移均摊O(C),所以得到O(n*C)的算法.
树形依赖背包问题:给定 树形依赖背包问题:给定n 件物品和一个背包 .第i件物品 的价值是 i ,其体积为 i,但是 件物品 的价值是W 其体积为V 依赖于第X 件物品(必须选取X 后才能取i, 依赖于第 i件物品(必须选取 i后才能取 ,如 果无依赖则X ),依赖关系形成森林, ),依赖关系形成森林 果无依赖则 i=0),依赖关系形成森林,背包 的容量为C. 的容量为 .可以任意选择装入背包中的物品 求装入背包中物品的最大总价值. ,求装入背包中物品的最大总价值.
v+5 av+5
…… ……
最后得到新的Fi,就完成了对子节点s的更新.
1 2 3 4 5 6 7 8 9 10
PROCEDURE DEAL i , C FOR s: = 1 TO n IF s 是 i 的子节点 THEN Fi → Fs DEAL s , C – Vs FOR K: =Vs TO C END FOR END IF END FOR //背包容量减小Vs //求两者的并 //
泛化物品的和: 泛化物品的和: 把两个泛化物品合并成一个泛化物品的运算, 把两个泛化物品合并成一个泛化物品的运算, 就是枚举体积分配给两个泛化物品,满足: 就是枚举体积分配给两个泛化物品,满足: G[j] = max{ G1[j-k] + G2[k] } (C>=j>=k>=0) 把两个泛化物品合并的时间复杂度是O(C^2). 这个概念也引自《背包九讲》.
我们可以把每一份分开处理,假设现在要考虑 余数为d的部分. 用j来标号,规定编号j所对应的体积是d+j*v.
编号j 编号 对应体 积
0 d
1 d+v
2 3 4 …… d+2*v d+3*v d+4*v ……
显然编号j可以从编号j-k到j中的任意一个转移 而来,因为相邻的体积正好相差v.
区间[j-k,j],这个区间是随着j的递增而左右边 界都递增的区间. 但是注意到由于不同编号对应的体积也是不一 样的,显然体积大的价值也会大于等于体积小 的,直接比较是没有意义的,所以还需要做一 定的修正.
这个概念最初是由DDengi在《背包九讲》中提 出. 定义:考虑这样一种物品, 定义:考虑这样一种物品,它并没有固定的费 体积)和价值, 用(体积)和价值,而是它的价值随着你分配 给它的费用(体积)变化而变化. 给它的费用(体积)变化而变化.
泛化物品可以用一个一维数组来表示体积与价 值的关系G[j]表示当体积为j的时候,相对应的 价值为G[j] (C>=j>=0). 显然,之前的背包动规数组Fi,就是一件泛化 F 物品,因为Fi[j]表示的正是体积为j的时候的最 大价值.同样的,多件物品也是可以合并成一 件泛化物品.
对于这个问题,我们可以把每棵子树看作是一 个泛化物品,那么一棵子树的泛化物品就是子 树根节点的这件物品的泛化物品与由根所连的 所有子树的泛化物品的和. 这就是一个O(n*C^2)的算法.
泛化物品与一件物品的和: 泛化物品与一件物品的和: 把一个泛化物品与一件物品合并成一个泛化物 可以用类似于0 品,可以用类似于 - 1背包经典动规的方法求 背包经典动规的方法求 出. 泛化物品的并: 泛化物品的并: 因为两个泛化物品之间存在交集, 因为两个泛化物品之间存在交集,所以不能同 时两者都取, 时两者都取,那么我们就需要求泛化物品的并 对同一体积, ,对同一体积,我们需要选取两者中价值较大 的一者,效率O(C). 的一者,效率 .
考虑对以i为根的子树的处理,假设当前需要处 理i的一个子节点s,体积v,价值w. 如果我们在当前的Fi中强制放入物品s后作为以s 为根的子树的初始状态的话,那么处理完以s为 s 根的子树以后,Fs就是与Fi有交集的泛化物品( 实际上是Fs包含Fi),同时,Fs必须满足放了物 品s,即Fs[j] (v>j>=0)已经无意义了,而 Fs[j](C>=j>=v)必然包含物品s. 下一步只要求Fs与Fi的并,就完成了对一个子节 点的处理.
2 b2
3 b3
4 b4 Fs
5 b5
…… ……
i
i
s
必然包含
s
再通过求Fi与Fs的并来完成对子节点s的更新.
编号
Fs
0 1 2 3 4 5 …… b0+w b1+w b2+w b3+w b4+w b5+w ……
更 新
编号
Fi
v av
v+1 av+1
v+2 av+2
v+3 av+3
v+4 av+4
由背包转变出的题有很多,其中不乏难题,今 天给大家介绍了两种最常见的变形,最后都以 O(n*C)的算法解决了. 就目前来说,背包类的题目还有很多没有得到 很好的解决,等待着大家去继续探索研究.
特别感谢 白彦博 金圣玺 冯一 参考资料 Ddengi的《背包九讲》
徐持衡 浙江省温州中学
�
对于当前节点i,我们找到一个子节点s.
编号
Fi
0 a0
1 a1
2 a2
3 a3
4 a4
5 a5
…… ……
把Fi赋值给Fs,作为这棵子树的初始状态.
编号
Fs
0 a0
1 a1
2 a2
3 a3
4 a4
5 a5
……ቤተ መጻሕፍቲ ባይዱ……
s
i
递归处理以s为根的子树.
递归后就得到了最终的Fs.
编号
Fs
0 b0 Fi
1 b1
对于一个左右边界都只增不降的区间最值,可 以用单调队列来做到总效率O(n)的维护. 如果要用单调队列来优化多次背包,就必须在 多次背包问题中挖掘出一个维护区间最值的子 问题.
对于多次背包,用最常见的状态表示是用F[i,j] 表示前i种物品,总体积不超过j的最大价值总 和. 当前只考虑第i种物品,假设体积v,价值w,数 i v w 量k. 由于对于体积j,与其相关的只有那些对v的余 数与j相同的体积,所以再按照体积j对v的余数 分为v份.
多次背包问题:给定 种物品和一个背包. 多次背包问题:给定n 种物品和一个背包.第i 的价值是W 其体积为V 数量是K 种物品 的价值是 i ,其体积为 i,数量是 i件 背包的容量为C. ,背包的容量为 .可以任意选择装入背包中 的物品,求装入背包中物品的最大总价值. 的物品,求装入背包中物品的最大总价值.