问题
现有n种珠宝,每种都有无穷多+∞个,已知第i个珠宝的价值是vi,重量是wi。给你一个背包,你可以自由挑选珠宝装到背包中,但背包可以装载的最大重量为weight。求背包能够装载珠宝的最大价值value。
解法
设f(i,j)为背包中放入前i件物品,重量不大于j的最大价值,其中i∈[1,n],j∈[0,weight]。有如下状态转移方程:
f(i,j)={0max(f(i−1,j),f(i−1,j−k×wi)+k×vi)(initialize)(loop)i∈[0,n],j∈[0,weight]i∈[1,n],j∈[1,weight],j≥k×wi,k≥0 (1) 初始化,背包中没有放入任何珠宝时f(i,j)=0;
(2) 对于第i种珠宝,若装入背包k个,则背包价值增大k×vi,背包的剩余重量减小k×wi(其中k≥0,j≥k×wi),即f(i,j)=f(i−1,j−k×wi)+k×vi;若不装入背包,则一切维持不变,即f(i,j)=f(i−1,j)。选择这两种情形中的最大值;
f(n,weight)即为n个珠宝中重量不超过weight的最大价值。该算法的时间复杂度是O(n×weight2),因为状态转移方程中的参数k的规模与背包最大重量weight线性相关。
源码
CompleteBag.h
CompleteBag.cpp
测试
CompleteBagTest.cpp