Source
The classic problem of dynamic programming
The classic problem of backpack in the dynamic planning, once done once, before doing this topic, the use of the idea is greedy, greedy can also get the solution, but sometimes this solution is not optimal;
Use the dynamic programming idea to do this problem once, refer to the Backpack nine talk (really good, before some do not understand the place, now understand deeper)
This is the most basic knapsack problem, characterized by: only one piece of each item, you can choose to put or not put.
Define the state with sub-question: F[i][v] Indicates the maximum value that the first I item can get in a backpack with a capacity of V. The state transfer equation is:
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
This equation is very important, and basically all the equations for knapsack-related problems are derived from it. So it is necessary to explain it in detail: "Put thefirst I item into a backpack with a capacity of V" This sub-problem, if only consider the article I item strategy (put or not), then can be converted into a only 1 items of the first I-item problem. If you do not put the article I item, then the problem is converted to "the first I-1 items into the capacity of the backpack", the value of f[i-1][v]; If you put the article I, then the problem is converted to "the first I-1 items into the remaining capacity of v-c[i] backpack", the maximum value can be obtained is f[ I-1][v-c[i]] plus the value obtained by placing the item in article I w[i].
The above content refers to the first in the nine-story backpack, the solution is N (nv) in time complexity, more efficient, but in the space complexity can also be optimized;
Here is the simplest way to write: Spatial complexity can also be optimized, dynamic programming is generally more streamlined, but it is to understand the state expression;
#include <cstdio> #include <cstring> #define MAX (A, b) a>b?a:bconst int maxn=1001;int c[maxn],w[maxn],dp[ Maxn][maxn];int Main () { int n,v,i,j; while (scanf ("%d%d", &n,&v) &&n&&v) { memset (dp,0,sizeof (DP)); for (i=1;i<=n;i++) scanf ("%d%d", &c[i],&w[i]); for (i=1;i<=n;i++) for (j=1;j<=v;j++) { if (J<c[i]) dp[i][j]=dp[i-1][j];//state expression Else Dp[i][j]=max (Dp[i-1][j],dp[i-1][j-c[i]]+w[i]); } printf ("%d\n", Dp[n][v]);} }
Optimize the memory of the writing, the DP of the two-dimensional array into a one-dimensional array, not the array to store the value of the backpack; using one-dimensional array to solve knapsack problem, in a lot of places will also be used, must master this usage;
#include <cstdio> #include <cstring> #define MAX (A, b) a>b?a:bconst int maxn=1001;int Dp[maxn];int main () { int n,v,i,j,c,w; while (scanf ("%d%d", &n,&v) &&n&&v) { memset (dp,0,sizeof (DP));//Initialize for (i=1;i <=n;i++) { scanf ("%d%d", &c,&w); for (j=v;j>=c;j--) Dp[j]=max (dp[j],dp[j-c]+w);//recursion Relationship } printf ("%d\n", Dp[v]); } return 0;}