An ultimate backpack question that combines all the backpacks. If you do this, the backpack will be okay.
Question: give you a description of N types of items, backpack capacity d
Each type has three attributes, k e p.
K indicates the maximum number of such items to be selected. If it is 0, an unlimited number of items can be selected.
E indicates the value of each item in this category.
P indicates the cost of each item
If this is the case, the question will be too watery, and multiple backpacks will be OK.
So I added some points to the question, and I thought about it for a long time.
The topic also divides some types of items into groups. Each group can only select one category of items.
That is to say, it is not long to add a group backpack to multiple backpacks, but think carefully and find that each group of items is composed of some types of items, you can only select one type, and each type of item has its own nature.
The procedure is as follows:
Open a temporary array to record the status of the items of the group type. W [I] [J] indicates the maximum profit (equivalent to preprocessing) when the capacity of the item in Group I is J)
Other ungrouped items can be carried out with multiple backpacks.
For details, seeCode(If you are not very familiar with all kinds of backpacks, check the backpack first)
View code
# Include <cstdio># Include <Cstring> # Include <Vector> # Include <Algorithm> Using Namespace STD; Const Int Maxn = 1500 ; Const Int INF = ~ 0u > 2 ; Struct Node { Int K, E, P ;} In [Maxn]; Int DP [maxn]; Int N, m; Char S [ 100000 ]; Int Flag [maxn]; Void Init ( Int DP []) {fill (DP, DP + M + 1 ,- INF); DP [ 0 ] = 0 ;} Void Complete ( Int W, Int Val, Int DP []) { For ( Int I = W; I <= m; I ++) If (DP [I-W]>-INF) DP [I] = max (DP [I-W] +Val, DP [I]);} Void Zero_one ( Int W, Int Val, Int DP []) { For ( Int J = m; j> = W; j --) If (DP [J-W]>-INF) DP [J] = max (DP [J-W] + Val, DP [J]);} Int W [ 10 ] [Maxn]; Int TMP [maxn]; Int Main (){ While (Scanf ( " % D " , & N, & M )! = EOF ){ For ( Int I = 1 ; I <= N; I ++) scanf ( " % D " ,& In [I]. K ,& In [I]. E ,& In [I]. P ); Int G; scanf ( " % D " ,& G); getchar (); vector < Int > Group [ 10 ]; Memset (flag, 0 , Sizeof (FLAG )); For ( Int I = 1 ; I <= g; I ++ ) {Gets (s ); Int Len = Strlen (s ); For ( Int J = 0 ; J < Len ;){ If (S [J]> = ' 1 ' & S [J] <= ' 9 ' ){ Int Sum = 0 ; While (S [J]> = ' 0 ' & S [J] <= ' 9 ' ) {Sum = Sum * 10 + S [J]- ' 0 ' ; J ++ ;} Flag [Sum] = I ;} Else J ++ ;}} Init (DP ); For ( Int I = 1 ; I <= g; I ++ ) Init (W [I]); For ( Int I = 1 ; I <= N; I ++ ){ If (Flag [I]) Init (TMP ); If ( In [I]. k = 0 | In [I]. K * In [I]. P> = M) complete ( In [I]. P, In [I]. E, flag [I]? TMP: DP ); Else { Int K = 1 , Count = In [I]. K; While (K < Count) {zero_one (K * In [I]. P, In [I]. E * k, flag [I]?TMP: DP); count -= K; k <= 1 ;} Zero_one (count * In [I]. P, count * In [I]. E, flag [I]? TMP: DP );} If (Flag [I]) For ( Int J = 0 ; J <= m; j ++) W [flag [I] [J] =Max (W [flag [I] [J], TMP [J]);} For ( Int I = 1 ; I <= g; I ++ ) For ( Int V = m; V> = 0 ; V -- ) For ( Int J = 0 ; J <= V; j ++ ) If (DP [V-J]>-INF & W [I] [J]>- INF) DP [v] = Max (DP [v], DP [V-J] + W [I] [J]); If (DP [m]> = 0 ) Printf ( " % D \ n " , DP [m]); Else Printf ( " I'm sorry... \ n " );} Return 0 ;}