A clever operation for this question is to agree to take out the lower bound for a given range, and then convert it into a multi-backpack problem. Binary optimization is used.
CodeAs follows:
# Include <cstdlib> # Include <Cstring> # Include <Cstdio> # Include <Cmath> # Include <Algorithm> # Include <Iostream> # Define Er 0x80808080 Using Namespace STD; /* Problem-solving: Given a multi array and a pairs array, the best table array is required. to meet these requirements, sum {table [I] * multi [I]} = 0 and the maximum solution of sum {table [I] * pairs} is required: calculate the lower bound as a part. Therefore, [L [I], U [I] is converted to [1, U [I]-l [I] multiple backpacks. both M [I] and P [I] perform separate lower bound calculations. calculate T = L [1] * m [1] + L [2] * m [2]... then there is a multi-backpack with just enough t capacity. */ Int N, P [ 205 ], M [ 205 ], L [ 205 ], U [ 205 ]; Int Lim, DP [ 100005 ]; Void Zobag ( Int W, Int P ){ For ( Int I = lim; I> = W ;-- I ){ If (DP [I-W]! = Er) DP [I] = Max (DP [I], DP [I-W] + P );}} Int DP (){ Int Q, N, K; DP [ 0 ] = 0 ; For ( Int I = 1 ; I <= N; ++ I ){ // Lists the item numbers. K = 1 ; While (U [I]-k> 0 ){ // If so many pieces can be separated Zobag (K * m [I], K *P [I]); U [I] -= K; k <= 1 ;} If (U [I]) zobag (U [I] * M [I], U [I] * P [I]);} Return DP [Lim];} Int Main (){ Int RET; While (Scanf (" % D " , & N )! = EOF) {Lim = Ret = 0 ; Memset (DP, 0x80 , Sizeof (DP )); For ( Int I = 1 ; I <= N; ++ I) {scanf ( " % D " , & P [I], & M [I], & L [I], & U [I]); Lim + = L [I] * m [I], U [I]-= L [I]; RET + = L [I] * P [I]; // P [I] also needs to calculate the lower bound, and then add it back. } Lim * =- 1 ; // It must be a number not greater than 0, because it is already the minimum value, and the final result of the question is 0. Printf ( " % D \ n " , Dp () + RET );} Return 0 ;}