(This old man's explanation won my mind, Special Recommendation: http://blog.csdn.net/insistgogo/article/details/8579597)
There are n items and a backpack with a capacity of v. The cost of the I-th item is C [I], and the value is W [I]. Solving which items are loaded into a backpack can make the total cost of these items not exceed the capacity of the backpack, and the total value is the largest.
Point:
1. Each item has only one item. You can choose to put it or not.
2. Sub-problem --- put the first I items into a backpack with a capacity of v. The sum of values is f [I] [v].
If you only consider the I-th item Policy (put or not put), then it can be converted into a problem that only involves the previous I-1 items.
① I put: --- put the first I-1 items into the capacity of V-C [I] in the backpack. At this time, the sum of values is f [I-1] [V-C [I] + W [I];
② I pieces do not put: --- put the first I-1 items into the capacity of V backpack. At this time, the sum of values is f [I-1] [v];
The state transition equation can be obtained:F [I] [v] = max {f [I-1] [v], F [I-1] [V-C [I] + W [I]}.(Important !!!)
The Code is as follows (http://blog.csdn.net/insistgogo/article/details/8579597)
1 # include <iostream> 2 using namespace STD; 3 4 const int n = 3; // number of items 5 const int v = 5; // maximum backpack capacity 6 int weight [n + 1] = {,}; // item weight 7 int value [n + 1] = }; // The value of an item is 8 9 int f [n + 1] [V + 1]; 10 11/* 12. Objective: to avoid exceeding the size of the backpack, maximum Value 13 14 sub-problem status: F [I] [J]: indicates the maximum value 15 16 state transition equation obtained by placing the first I item into a backpack with a capacity of J: f [I] [J] = max {f [I-1] [J], f [I-1] [J-weight [I] + value [I]} 17 18 initialization: F array is set to 019 */20 int knapsack () 21 {22 // initialize 23 memset (F, 0, sizeof (f); 24 // recursive 25 for (INT I = 1; I <= N; I ++) // enumerated items 26 {27 for (Int J = 0; j <= V; j ++) // enumerative backpack capacity 28 {29 F [I] [J] = f [I-1] [J]; 30 if (j> = weight [I]) 31 {32 F [I] [J] = max (F [I-1] [J], f [I-1] [J-weight [I] + value [I]); 33} 34} 35} 36 return f [N] [v]; 37} 38 39 int main () 40 {41 cout <knapsack () <Endl; 42 return 0; 43}
View code
3. Time and space complexity, O (V * n );
4. Optimization (the time complexity cannot be optimized, but the space complexity can be optimized to O (V )):
(If f [I] [v] is stored in a two-dimensional array, it can be optimized to a one-dimensional array f [v].) change the main loop:
Analysis: Now we use F [v] To save the intermediate state. what we want to achieve is that after the I-th loop, f [v] stores the maximum value of putting the first I object into capacity v.
Thoughts
① For F [I] [v], there must be a main loop I = 1 .. n, two-dimensional array f [I] [0 .. all values of V. (The size of the first I item is 0 ~ V's greatest value in the backpack ). Then, if only one array f [0 .. v]. can we ensure that f [I] [v] represents the state we defined after the end of the I-th loop?
② F [I] [v] is derived from two subproblems: F [I-1] [v] and f [I-1] [V-C [I, can we ensure that f [I] [v] is pushed (that is, when f [v] is pushed in the I Main Loop) can we get the values of F [I-1] [v] and f [I-1] [V-C [I?
----> In summary, we need to use v = V in each main loop .. 0 in order. f [v], this ensures that f [v] saves the value of status f [I-1] [V-C [I] when pushing f [v. (Do not understand? Below)
The pseudocode is as follows:
1 for i=1..N2 3 for v=V..04 5 f[v]=max{f[v],f[v-c[i]]+w[i]};
View code
F [v] = max {f [v], F [V-C [I] + W [I]};
Just like our transfer equation f [I] [v] = max {f [I-1] [v], f [I-1] [V-C [I] + W [I]}, the current F [V-C [I] is equivalent to the original f [I-1] [V-C [I].
· We can see that to get f [I] [v], we need to know f [I-1] [v] and f [I-1] [V-C [I], because we use a two-dimensional array to save the intermediate state, we can directly retrieve the two States. What about an array?
When we use a one-dimensional array to store the status, F [v] indicates that after I is executed (I items have been processed ), the maximum value of putting the first I object into capacity V, that is, the former f [I] [v]. Compared with the two-dimensional model, it hides the First-dimensional model. However, the two models have the same meanings, but f [v] has been repeatedly used for different I and I. Therefore, the result of the I-1 loop may also be overwritten !!
In order to find f [v], we need to know the benefits of putting the previous I-1 items in the bag of capacity V, that is, the benefits of putting the previous f [I-1] [v] and the items in the front I-1 into a backpack with a capacity of V-C [I, that is, the previous f [I-1] [V-C [I] + W [I].
Difficulty: Because we only use one-dimensional array storage, it is not as convenient to retrieve these two subproblems because the I-th loop may overwrite
The result of a I-1 loop. Now let's calculate the two values:
1) before the I-1 items put in the capacity V of the backpack brought about by the benefits, that is, the previous f [I-1] [v]:
Since f [v] stores the greatest value of putting the first I object into capacity V during the I-cycle, when we find the maximum value of putting the first I object into capacity V (that is, the previous f [I] [v]), we are executing the I-th loop, the value of F [v] is the value stored in the first I-1 cycle, and the value of F [v] is the maximum value of the first I-1 object in capacity v, that is, F [I-1] [v].
2) before the I-1 items put into the capacity of V-C [I] of the benefits of the backpack, that is, the previous f [I-1] [V-C [I] + W [I];
Because f [0 ~ V] is the result of the first I-1 cycle, that is, the first I-1 objects are placed in the capacity 0 ~ The maximum value of V, that is, F [I-1] [0 ~ V]. Before executing the I-th loop, f array in the V-C [I] location storage is we are looking for the first I-1 items placed in the capacity of V-C [I] of the benefits of the backpack (that is, the previous f [I-1] [V-C [I]), here we assume that items are stored from array subscript 1.
Causes of reverse enumeration capacity:
Note that we roll out the I state from the two States of the second I-1 loop, and V> V-C [I], then for the I loop, backpack capacity only when V .. when there is a zero loop, the system will first handle the situation where the backpack capacity is V, and the backpack capacity is V-C [I] after processing.
Specifically, because V-C [I] is not executed yet, therefore, F [V-C [I] stores the results of the first I-1 loop. That is, when the I-th loop is executed and the backpack capacity is V, F [v] Stores f [I-1] [v], f [V-C [I] Stores f [I-1] [V-weight [I].
On the contrary, if the I-th loop is executed, the capacity of the backpack is traversed in the order of 0. V to check whether the I-th item can be placed. When the I-th loop is executed and the backpack capacity is V, F [v] Stores f [I-1] [v], however, F [V-C [I] Stores f [I] [V-C [I].
Because, V> V-C [I], in the I cycle, when the carrying capacity of a backpack is V, the carrying capacity of a V-C [I] has been calculated, f [I] [V-weight [I] is stored in F [V-C [I]. That is to say, for the 01 backpack, it is wrong to enumerate the size of the backpack in ascending order.
Conclusion: if we change the circular order of V from the forward order to the order, then f [I] [v] is deduced by F [I] [V-C [I, it is not consistent with the meaning of this question, but it is another important backpack problem (full backpack) is the simplest solution, so it is necessary to learn to use only one-dimensional array to solve the 01 backpack problem.
----------------------------- I still don't understand the split line ------------------------------------------------------
In ascending order, what is the result of enumerating the size of a backpack? It will repeatedly load an item and make the greatest value as much as possible. Of course, it will not exceed the size of the backpack.
Bulk capacity in reverse order: the items in the backpack can be loaded at most once, maximizing the value. Of course, the size of the backpack will not exceed.
First, let's give an example:
List objects in reverse order
When I = 2, we require f [5]: indicates the maximum benefit of testing a backpack with a size of 5 in item 2. It indicates the condition of F array when I = 2, F [5] is obtained, and green is the value currently stored in the array. These values are I = 1 (the previous loop) stored in array F. it is equivalent to f [I-1] [v], while yellow is the value we require. Before f [5], F [5] = 5, that is, F [I-1] [5] = 5; f [5] = f [5-2] + 10 = 5 + 10 = 15> F [I-1] [5] = 5; therefore, F [5] = 15;
Note that when f [v] is evaluated, the referenced values of F [V-C [I] and f [v] are the results of the previous loop.
Sequential enumeration of items
When I = 2, we require f [5]: indicates the maximum benefit of testing a backpack with a size of 5 in item 2. Indicates the condition of the F array when I = 2 and f [5,
Green is the values currently stored in the array. These values are stored in the array F when I = 2 (this loop. It is equivalent to f [I] [v]. This is because we traverse the array F in ascending order. When we evaluate f [v], the value before V (0 ~ V-1) has been found in the I cycle.
The yellow color makes the required value. Before f [5] is obtained, F [5] = 5, that is, F [I-1] [5] = 5;
F [5] = f [5-2] + 10 = 10 + 10 = 20> F [I-1] [5] = 5; therefore, F [5] = 20;
The referenced f [3] is equivalent to f [I] [3] rather than the normal F [I-1] [3];
Note that when f [v] is evaluated, the f [V-C [I] referenced by F is the result of this loop, and f [v] is the result of the previous loop;
In other words, when the size of the backpack is 5, check whether item 2 is added. According to the state transition equation, we need to reference ourselves and f [3] In F [5]. because the backpack capacity is 3, you can load item 2, and the benefits are greater than the previous, so put into the backpack. When detecting f [5], the benefit of item 2 must be added, while F [5] When referencing f [3, f [3] has added item 2 once. Therefore, item 2 is added multiple times when the backpack capacity is enumerated.
Further, we observe the one-dimensional state transition equation:
F [I] [v] = max (F [I-1] [v], F [I-1] [V-C [I] + W [I])
First, let's clarify three issues
1) V-C [I] <v
2) state f [I] [v] is determined by F [I-1] [v] and f [I-1] [V-C [I;
3) For item I, when we enumerate the backpack capacity, as long as the backpack capacity can be loaded with item I, and the benefits are greater than the original, it will be successfully placed into item I.
Specifically, when we enumerate the size of a backpack, the V-C [I] <V will be calculated first. When the backpack capacity is V-C [I], once the item I is loaded, because f [v] needs to use F [I-1] [V-C [I], if f [v] can also be loaded with item I, then when the backpack capacity is V, it can be loaded with two items. If the V-C [I] was launched from the previous status and they also loaded item I, then the backpack with the capacity of V was loaded with item I multiple times.
Note: When calculating f [v], you have loaded all the items I can into a backpack with a capacity of V. At this time, the number of times that I can be loaded is the maximum.
In fact, sequential enumeration capacity is the simplest solution to the full backpack problem.
Initialization details
There are two ways to solve the problem of a backpack:
1) the maximum value that can be obtained without exceeding the backpack capacity
2) how much value can be obtained when a backpack is filled up?
The main difference is whether it is required to be filled with backpacks. However, the implementation methods of these two methods are different during initialization.
1) just filled with a backpack: Use a two-dimensional array f [I] [v] to store the intermediate state. The first dimension indicates the item, and the second dimension indicates the backpack capacity.
During initialization, all values except f [I] [0] = 0 (first column) are negative infinity.
Cause: the f array indicates the legal status when no item can be put into the backpack. For a backpack that happens to be filled with a size of 0 (the first column), it can be filled with any item without being loaded. This is a legal situation and the value is 0 at this time. Other f [0] [v] (the first line) cannot be full. At this time, there is no capacity or item. Other positions (except the positions in the first row and the first column) must be initialized to the negative infinity to compare the maximum values in the calculation. From the perspective of the program, we can only allow the starting position of the sequence of packed items to start from the first column. These starting positions are valid positions, in addition, all the results that can be filled are positive, and f [N] [v] is terminated.
Note: even if we want to fill up just the right amount, we still need to enumerate all the items that can be loaded into the backpack. As long as they can be loaded, they need to be loaded, and the benefits will increase. However, because the sequence of just filled items must start from a row in the first column, and the subsequent benefits must be positive. For a sequence of items not exactly filled, the starting position must start from a position in the first line. Because the sequence is initialized as negative infinity, it must be small when it comes to values that come with sequences of just-filled items. Therefore, we can finally obtain the maximum value.
2) You don't need to fill your backpack, but you only need to maximize the benefits.
Use a two-dimensional array f [I] [v] to store the intermediate state. The first dimension indicates the item, and the second dimension indicates the backpack capacity.
During initialization, all values except f [I] [0] = 0 (first column) are negative infinity.
The one-dimensional array f [v] is used to store the intermediate state. dimensions indicate the size of the backpack. If the backpack does not have to be filled up, a valid solution is provided for any capacity backpack ", the value of this solution is 0, so the initial state value is all 0.
Summary
01 the backpack problem is the most basic problem. It contains the most basic idea of the design state and equation in the backpack problem. In addition, other types of knapsack problems can also be converted to 01. Therefore, you must carefully understand the methods of the above basic ideas, the significance of the state transition equation, and how to optimize the space complexity.
Full backpack optimization: (to be continued)
① Simple Optimization
1) remove items with a fee greater than v;
2) If two I items meet the requirements of C [I]> = C [J] & W [I] <= W [J], you do not need to consider removing item I;