Do a period of time Noi, do dynamic planning to read a few days algorithmic books. Or not in-depth, learning the basic dynamic planning, a little bit of experience, recorded here.
Backpack is a kind of problem: under the premise of limiting the total quality, from a number of quality \ Price pairs, which can make the most price.
The dynamic programming is a kind of thought, simply speaking, the dynamic programming idea is to make full use of the calculation result of the pair problem to recursive the parent problem result. Therefore, the dynamic programming has high efficiency, eliminating some unnecessary calculation. Here the main concern table and recursive relationship, in fact, these two are the same thing, according to the record table to push the solution of the parent problem, to find a recursive relationship to rely on the table record sub-problem solution. Different problems have different ways of building, so I personally feel that beginners do not need to read the theory and then directly to write code, you can see how other people write code. While debugging code side to understand the idea of more efficient, but this is not their own things, need some practice. Dynamic planning is a kind of thought, but to solve different types (characteristics) of the problem has a different breach, which also led to the dynamic planning of different problems of the resolution code differences are also large, the same reason, the same type of problem code framework structure is the same, to master a class of problem analysis methods and coding framework are necessary, The two complement each other, just as we are going to output an array of all the elements, and everyone will immediately get the for-while statement to use.
Now look at the knapsack problem is how to use the record table to solve the problem efficiently, there is a set of sample data:
4 7 1 2 3 1 5 Ten 4 One
Among them, the first line is the quality \ price of the number and the maximum allowable quality, recorded as n=4,w=7. The following 4 lines are preceded by quality, followed by the price, can be recorded with two arrays can also be used structure. Obviously, the choice of items 1 and 4 can reach a value of 13 (quality 5). Now let's take a look at the record table to solve this problem:
MwOID 0 1 2 3 4 5 6 7
00 0 0 0 0 0 0 0
1 21 0 2 2 2 2 2 2 23 12 0 2 2 2 3 3 3 35 103 0 2 2 2 3 Ten A A4 114 0 2 2 2 One - - -
The table fills the line from left to right and then fills the next line from left to right. Where the Green line is the maximum selection of the item's range subscript OID (for example, oid=2 is selected from two items numbered 1, 2), and the red line is the current allowable maximum mass curw--This is the idea of dynamic planning to solve knapsack problem, starting from 0 capacity backpack, so that after 1 has been hand-pushed to the maximum backpack capacity The data part of the table is the record value--TABLE[OID][CURW] records the maximum value that can be loaded into a pack of CURW sizes in the previous OID items. So, whether a 01 backpack, a full backpack, a partial backpack or a similar problem with dynamic planning is a code framework (especially 01 and complete, the code is 2 pips). Now we're thinking about a couple of questions:
1, knapsack problem for any one of the items, there are only two states: take, not take. So, how do you write the codes for both of these states?
In fact, the problem is relatively simple, as long as the current backpack quality does not reach the current quality of the goods, it does not need to load, to try to mount, that is:
if (curw<warr[oid]) { //not loaded }Else{//try loading }
2, how to try to load?
Do you remember the maximum value of the CURW-sized backpack that you can load? The two are also the same problem, in order to ensure that CURW save the maximum value, we need to try to put the current items into the backpack. So how do you get the maximum value before you put it in your backpack? Table[oid][curw-warr[oid]] It is because we have recorded the maximum value of any quality from 0 to CURW (which is also the reason for the traversal from the CURW to the MAXW, and also the breach of the optimization), So this value is not put into the current item maximum value, do not worry about the size of curw-warr[oid], here curw-warr[oid]>=0. OK, now calculate the value of the item after it has been put in the backpack: table[oid][curw-warr[oid]]+varr[oid]. This is an attempt, by trying to put in the current item, we know the maximum value after putting it in, but this value is not necessarily bigger than the time we put it-remember we took out "part of the item"? Review how I know the maximum value when not putting an item, it causes us to lose some items, of course, it may not be lost. So now we need to find the largest one in the value of table[oid][curw-warr[oid]]+varr[oid] and the maximum value TABLE[OID][CURW when we don't try to put this item in. Then put the code below to make it easier to navigate:
intdp () { for(intOid=0; oid<n;oid++) { for(intcurw=0; curw<=w;curw++) { if(curw<Warr[oid]) {table[oid+1][curw]=TABLE[OID][CURW]; }Else{table[oid+1][curw]=max (table[oid][curw],table[oid][curw-warr[oid]]+varr[oid]); } printf ("% 2d", table[oid+1][CURW]); } cout<<Endl; } returntable[n][w];}
According to the above analysis, it is obvious to start with a 0-capacity backpack, and the item will be used when the value of no item ("Take part of it"), so the internal and external loop here starting from 0. Of course, if you modify the code without using oid+1 and use the OID directly, there will be some difference. However, the underlying data used for recursion--table part of the table needs to be initialized:
for (i=0; i<=n;i++) table[0][i]=0;
The complete code is as follows:
#include <iostream>#include<algorithm>using namespacestd; intn,w; intwarr[ -]={0}; intvarr[ -]={0}; inttable[ -][ -]; intdp () { for(intOid=0; oid<n;oid++) { for(intcurw=0; curw<=w;curw++) { if(curw<Warr[oid]) {table[oid+1][curw]=TABLE[OID][CURW]; }Else{table[oid+1][curw]=max (table[oid][curw],table[oid][curw-warr[oid]]+varr[oid]); } printf ("% 2d", table[oid+1][CURW]); } cout<<Endl; } returntable[n][w];}intMain () {inti; CIN>>n>>W; for(i=0; i<=n;i++) table[0][i]=0; for(i=0; i<n;i++) cin>>warr[i]>>Varr[i]; cout<<DP ();}
01 Backpack and dynamic planning