CompleteBag 完全背包

问题

现有nn种珠宝,每种都有无穷多++ \infty个,已知第ii个珠宝的价值是viv_{i},重量是wiw_{i}。给你一个背包,你可以自由挑选珠宝装到背包中,但背包可以装载的最大重量为weightweight。求背包能够装载珠宝的最大价值valuevalue

解法

f(i,j)f(i,j)为背包中放入前ii件物品,重量不大于jj的最大价值,其中i[1,n]i \in [1,n]j[0,weight]j \in [0,weight]。有如下状态转移方程:

f(i,j)={0(initialize)i[0,n],j[0,weight]max(f(i1,j),f(i1,jk×wi)+k×vi)(loop)i[1,n],j[1,weight],jk×wi,k0f(i,j) = \begin{cases} 0 & (initialize) & i \in [0,n], j \in [0,weight] \\ max(f(i-1,j),f(i-1,j-k \times w_{i}) + k \times v_{i}) & (loop) & i \in [1,n], j \in [1,weight], j \geq k \times w_{i}, k \geq 0 \end{cases}

(1)(1) 初始化,背包中没有放入任何珠宝时f(i,j)=0f(i,j) = 0

(2)(2) 对于第ii种珠宝,若装入背包kk个,则背包价值增大k×vik \times v_{i},背包的剩余重量减小k×wik \times w_{i}(其中k0,jk×wik \geq 0, j \geq k \times w_{i}),即f(i,j)=f(i1,jk×wi)+k×vif(i,j) = f(i-1,j-k \times w_{i}) + k \times v_{i};若不装入背包,则一切维持不变,即f(i,j)=f(i1,j)f(i,j) = f(i-1,j)。选择这两种情形中的最大值;

f(n,weight)f(n,weight)即为nn个珠宝中重量不超过weightweight的最大价值。该算法的时间复杂度是O(n×weight2)O(n \times weight^2),因为状态转移方程中的参数kk的规模与背包最大重量weightweight线性相关。

源码

CompleteBag.h

CompleteBag.cpp

测试

CompleteBagTest.cpp

Last updated