First, review the 01 backpack:

01 The backpack is in the m pieces of items taken out several pieces placed in the space W backpack, the volume of each item is W1,W2 ... Wn, corresponding to the value of P1,P2 ... Pn.

Find the solution to get the most value. Note: In the subject, all the volume values are integers. Ideas:

**consider using the dynamic programming method to solve, here: The stage is: in the first n items, select a number of items into the backpack; the state is: in the first n items, select a number of items into the remaining space in the backpack of W can obtain the maximum value; The decision is: Nth item put or not put The dynamic transfer equation can be written as follows: we use F[I,J] to indicate the maximum value that can be obtained in a backpack with the remaining space J in the first I-item** .
**f[i, j] = max (f[i-1, J-wi] + Pi (J >= Wi), F[i-1, J])**
**[1] This equation is very important, basically all of the knapsack-related problems of the equation is derived from it. So it is necessary to explain it in detail: "Put the first 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 I do not put the article I, then the problem is converted to "the first I-1 items into the backpack of the capacity V", the value of f[v]; If you put the article I, then the problem translates to "the first I-1 items into the remaining capacity of v-c backpack", the maximum value can be obtained is f[v-c] Plus the value obtained by placing the article I item W. **
Oversized knapsack problem: There are n items with a weight and value of w[i] and V[i], from which the total weight of items not exceeding W is selected, and the maximum value of the sum of the values in all selection schemes is obtained. Among them, 1≤n≤40, 1≤w[i], v[i]≤10^15, 1≤w≤10^15.

Idea: The first feeling is the ordinary 01 backpack. However, after reading the data range will find that the value and weight can be very large values, compared to n is relatively small. The complexity of solving backpacks with DP is O (NW), and therefore cannot be used to solve this problem. At this point we should use the small characteristics of N to find other methods.

There are a total of 2^n for selecting items, so it is not possible to enumerate them directly, but if you divide the items into two halves and then enumerate them, it is feasible because each part has a maximum of 20. We take the first half of the selection method corresponding to the weight and value of the sum of W1, v1, so that in the second half of the total weight w2≤w-w1 to make V2 the largest selection method can be.

Therefore, we want to think about the efficient way to find max{v2|w2≤w '} from the enumeration (W2,V2) collection. First of all, obviously we can exclude all w2[i]≤w2[j] and V2[i] >= V2[j] J. This can be done according to W2, V2 dictionary ordering. Then the remaining elements satisfy W2[i] < W2[J] <=> V2[i] < V2[j], if you want to calculate MAX{V2|W2 <= W '}, just look for the largest I that satisfies W2[i] <= W '. This can be done with a two-point search, the remaining number of elements is m, a search requires O (LOGM) time. Because m≤2^ (N/2), the total time complexity of this algorithm is O (n * 2^ (N/2)), which can be solved within the implementation.

Code:

#include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <vector> #include <queue > #include <string.h> #include <iostream> #include <algorithm>using namespace Std;const int MAXN =50 ; const long long inf=0x3f3f3f3f;typedef long long ll;int n,m,i,j; LL W[MAXN],V[MAXN]; LL w;pair<ll, ll> vec[1 << (MAXN/2)]; weight, value inline int input () {int res=0,f=1,c; while (!isdigit (c = GetChar ()) && c!= '-'); c== '-'? f=0:res=c-' 0 '; while (isdigit (c = GetChar ())) res = res*10 + C ' 0 '; Return f? Res:-res;} void Solve () {int n2=n/2; for (int i=0; i<1<<n2; i++) {LL sw=0,sv=0; for (int j=0; j<n2; J + +) {if (i>>j&1) {sw+=w[j]; SV+=V[J]; }} vec[i]=make_pair (SW,SV); } sort (vec,vec+ (1<<n2)); int m=1; for (int i=1; i<1<<n2; i++) {if (vec[m-1].second<vec[i].second) {Vec[m++]=vec[i]; }} LL res=0; for (int i=0; i<1<< (N-N2); i++) {LL sw=0,sv=0; for (int j=0; j<n-n2; J + +) {if (i>>j&1) {sw+=w[n2+j]; SV+=V[N2+J]; }} if (sw<=w) {LL ans= (Lower_bound (Vec,vec+m,make_pair (W-sw,inf))-1)->second; Res=max (Res,sv+ans); }} printf ("%lld\n", res);} int main () {while (~scanf ("%d%lld", &n,&w)) {//printf ("%d\n",1<< (MAXN/2)); for (i=0; i<n; i++) {scanf ("%lld%lld", &w[i],&v[i]); } solve (); printf ("%lld\n", w[n-1]*v[n-1]); } return 0;}

Oversized Backpack (Challenge programming 01 backpack)