Source: Internet
Author: User

01 Backpack

There are n different items, each item has two attributes, size volume, value value, now to a backpack with a capacity of W, ask the most can take away how much value of the goods.

int f[w+1]; F[X] Indicates the maximum value for the backpack capacity X for (int i=0; i<n; i++) for (int j=w; j>=size[i]; j--) f[j] = max (f[j), f[j-size[ I]]+value[i]);

Full backpack

If the item does not count for more than one item, you can change it slightly.

for (int. i=0; i<n; i++) for (int j=size[i]; j<=w; j + +) f[j] = max (F[j], f[j-size[i]]+value[i]);

F[W] that is the request

There are two types of initialization:

1, if the backpack requirements just fill the initialization f[0] = 0, f[1~w] =-inf;

2, if do not need just fill f[0~v] = 0;

Example:

01 Backpack

v=10,n=3,c[]={3,4,5}, w={4,5,6}

(1) The backpack is not necessarily filled

The order of calculation is: from right to left, top down: Because each item can only be placed once, the front of small volume will affect the volume of large

(2) The backpack just fills up

The order of calculation is: from right to left, top to bottom. Note the initial value, where-inf represents a negative infinity

Full backpack:

v=10,n=3,c[]={3,4,5}, w={4,5,6}

(1) The backpack is not necessarily filled

The order of calculation is: From left to right, top-down: Each item can be put several times, the front will affect the back

(2) The backpack just fills up

The order of calculation is: From left to right, top to bottom. Note the initial value, where-inf represents a negative infinity

Multi-pack:

Multi-pack problem requirements are simple, that is, each item gives a certain number of pieces, the maximum value can be obtained

&N Bsp Multi-backpack conversion to 01 knapsack problem is a more initialization, the number of pieces of C in binary decomposition into a number of pieces of the set, the number can be combined into any number less than or equal to C, and will not be repeated, the reason is called binary decomposition, because this decomposition can be interpreted in binary form of numbers

For example: 7 binary 7 = 111 It can be decomposed into 001 010 100 These three numbers can be combined into any number less than or equal to 7, and each combination will be different The number

&NBSP;15 = 1111 can be decomposed into 0001 0010 0100 10,004 numbers

&nbs p; If 13 = 1101 is decomposed to 0001 0010 0100 0110 The first three digits can be combined into any number within 7, i.e. 1, 2, 4 can be combined into all the numbers within the 1--7, plus 0 110 = 6 can be combined into any one greater than 6 is less than or equal to 13 of the number, such as 12, can make the preceding contribution 6 and the subsequent contribution 6 on the line. Although there are repeated but always can take 13 of all the numbers are taken into account, based on this idea to convert multiple items into, a variety of items, can be solved by 01 backpack.

See code:

int n; Enter the number of items int C; How many pieces of int v are there for each item ; The value of each item int s; The size of each item int count = 0;//How many items can be obtained after decomposition int value[max];//used to preserve the value of the decomposed item int Size[max]; Used to save the decomposed item volume scanf ("%d", &n); Enter the number of items first, then the decomposition of each item while (n--) ///Then enter N in this item { scanf ("%d%d%d", &c, &s, &v); Enter the number and value of each item for (int k=1; k<=c; k<<=1) //<< right shift equals multiply by two { value[count] = k*v; size[count++] = k*s; c-= k; } if (C > 0) { Value[count] = c*v; size[count++] = c*s; } }

Theorem: A positive integer n can be decomposed into 1,2,4,..., 2^ (k-1), n-2^k+1 (k is the largest integer that satisfies n-2^k+1>0), and all integers within 1~n can be uniquely represented as 1,2,4,..., 2^ (k-1), n-2^k+ 1 in the form of a certain number of numbers.

The proof is as follows:

(1) Sequence 1,2,4,..., 2^ (k-1), and the N of all elements in n-2^k+1, so the range of several elements is: [1, N];

(2) If the positive integer t<= 2^k–1, then T must be able to use 1,2,4,..., 2^ (k-1) Some number of the and expression, this is easy to prove: We put the binary representation of T, it is obvious that T can be expressed as n=a0*2^0+a1*2^1+...+ak*2^ (k-1), where ak=0 or 1, indicates that the AK bit of T is a binary number 0 or 1.

(3) If t>=2^k, set s=n-2^k+1, then t-s<=2^k-1, so T-S can be expressed as 1,2,4,..., 2^ (k-1) in the form of some number of, and then T can be expressed as 1,2,4,..., 2^ (k-1), The form of a certain number of numbers in S and (Addend must contain s).

(Certificate of completion. ）

Now, using Count instead of n is exactly the same as the 01 knapsack problem.

Hangzhou Electric 2191: This is a multiple backpack with 01 and a complete backpack:

#include <stdio.h> #include <string.h> int dp[102]; int p[102],h[102],c[102]; int n,m; void Comback (int v,int w)//expenses, weight. Full backpack; {for (int i=v; i<=n; i++) if (dp[i]<dp[i-v]+w) dp[i]=dp[i-v]+w;} void oneback (int v,in T W)//expenses, weight; 01 backpack; {for (int i=n; i>=v; i--) if (dp[i]<dp[i-v]+w) dp[i]=dp[i-v]+w;} int Main ( ) {int ncase,i,j,k; scanf ("%d", &ncase); while (ncase--) {memset (dp,0,sizeof (DP)); scanf ("%d%d", &n,&m);//funds, types; for (i=1; i<=m; i++) {scanf ("%d%d%d", &p[i],&h[ I],&c[i]);//value, weight, quantity; if (p[i]*c[i]>=n) Comback (P[i],h[i]); else {for (j=1; j<c[i]; j<<1) {oneback (j*p[i],j* H[i]); C[i]=c[i]-j; } oneback (P[i]*c[i],h[i]*c[i]); }} printf ("%d\n", Dp[n]); } return 0; }

Just use the 01 backpack and optimize with binary:

#include <iostream> using namespace std; int main () {int ncase,limit,nkind,i,j,k, v[111],w[111],c[111],dp[111]; V[] Storage value, w[] storage size, c[]//In the case, the value is the weight of rice, the size is the price of the meter int count,value[1111],size[1111]; Count stores the total number of items after decomposition//value The value of each item after the storage has been decomposed//size the size of each item after the storage has been decomposed cin>>ncase; while (ncase--) {count=0; cin>>limit>>nkind; for (i=0; i<nkind; i++) {cin>>w[i]>>v[i]>>c[i]; Binary decomposition for this kind of c[i] item for (j=1; j<=c[i]; j<<=1) {//<< left 1-bit, equivalent to multiply by 2 Value[count]=j*v[i]; Size[count++]=j*w[i]; C[i]-=j; } if (c[i]>0) {value[count]=c[i]*v[i]; Size[count++]=c[i]*w[i]; }}//After the decomposition of each item above,//now value[] is the decomposition of the value of the item//size[] stored is the decomposition of the item size//count is equivalent to the original n BelowThe 01 knapsack algorithm is used to solve the memset (Dp,0,sizeof (DP)); For (i=0, i<count; i++) for (j=limit; j>=size[i]; j--) if (Dp[j]<dp[j-size[i]]+value[i]) Dp[j]=dp[j-size[i]]+value[i]; cout<<dp[limit]<<endl; } return 0; }

Not optimized:

#include <iostream> #include <cstdio> #include <cstring> using namespace std; int value[105]; int cost[105]; int bag[105]; int dp[105]; int main () { int c,m,n; scanf ("%d", &c); while (c--) { scanf ("%d%d", &n,&m); for (int i = 1; I <= m; i++) scanf ("%d%d%d", &cost[i],&value[i],&bag[i]); Memset (Dp,0,sizeof (DP)); for (int i=1, i<= m; i++) for (int j=1; j<=bag[i]; j + +) for (int k=n; k>=cost[i]; k--) Dp[k]=max (DP [K], Dp[k-cost[i]]+value[i]); printf ("%d\n", Dp[n]); } return 0; }