HDU 3732 ahui writes word (multiple backpacks)
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 3732
Question:
Initially, there are n items, each of which has cost [I] costs and Val [I] values. You have m yuan. Now, I ask you how many items with a total value can you buy?
Where n <= 10 W, m <= 1 W. and cost [I] and Val [I] are in the range.
Analysis:
It is intuitive to use the 01 backpack directly at the beginning of this question. However, considering that the complexity of the 01 backpack is O (n * m), such a large complexity will certainly not work.
Then we find that each item is only related to its cost [I] and Val [I]. If the cost [I] and Val [I] of one or two items are exactly the same, we can combine these two items (we can see one item but the quantity is superimposed), and finally we can solve a problem of multiple backpacks directly. for multiple backpacks, the complexity is O (M * sum (log (Num [I]), where the sum of num [I] is N.
Initially, we read the input, sorted all the items, and then sorted them into N categories. Each type of item has multiple backpack problems with num [I.
If DP [I] [J] = X indicates the total cost of the I items before purchase <= J, the maximum value x can be obtained.
Initialization: DP is all 0.
For product I, there are two situations:
If Val [I] * num [I]> = m, perform a full backpack.
If Val [I] * num [I] <m, type I will be re-classified and k + 1 backpack will be created.
The final result is the value of DP [N] [M.
Program implementation, the rolling array is used for reverse recursion, so DP only has one dimension [J.
AC code:
# Include <cstdio> # include <cstring> # include <algorithm> using namespace STD; const int maxn = 121 + 5; int N; // n items int m after merging; // maximum spending value int Val [maxn]; // new category I item value int num [maxn]; // number of newly classified I items int cost [maxn]; // new category I item cost int DP [10000 + 5]; // 1 time 01 backpack process void zero_one_pack (INT cost, int Val) {for (INT I = m; I >= cost; I --) DP [I] = max (DP [I], DP [I-cost] + val );} // void complete_pack (INT cost, int Val) {for (INT I = cost; I <= m; I ++) DP [I] = max (DP [I], DP [I-cost] + val);} // void multiply_pack (INT cost, int Val, int sum) {If (Cost * sum> = m) {complete_pack (cost, Val); return;} int K = 1; while (k <sum) {zero_one_pack (Cost * k, Val * k); sum-= K; K * = 2;} zero_one_pack (Cost * sum, Val * sum );} // node is used to save each word attribute of the original input. struct node {int V, C; bool operator <(const node & RHs) const {return v <RHS. v | (V = RHS. V & C <RHS. c);} bool operator = (const node & RHs) const {return v = RHS. V & C = RHS. c ;}} nodes [100000 + 5]; int N; // The original n words int main () {While (scanf ("% d", & N, & M) = 2) {// read the input for (INT I = 1; I <= N; I ++) {char STR [20]; scanf ("% S % d", STR, & nodes [I]. v, & nodes [I]. c);} // combine the original input items and then classify them. Sort (nodes + 1, nodes + n + 1); n = 1; Val [N] = nodes [1]. v; cost [N] = nodes [1]. c; num [N] = 1; for (INT I = 2; I <= N; I ++) {If (nodes [I] = nodes [I-1]) num [N] ++; else {n ++; Val [N] = nodes [I]. v; cost [N] = nodes [I]. c; num [N] = 1 ;}// recursive output memset (DP, 0, sizeof (DP); For (INT I = 1; I <= N; I ++) multiply_pack (cost [I], Val [I], num [I]); printf ("% d \ n", DP [m]);} return 0 ;}
HDU 3732 ahui writes word (multiple backpacks)