B - True Sign in Question FZU - 2214 (Backpack)

Given a set of n items, each with a weight w[i] and a value v[i], determine a way to choose the items into a knapsack so that the total weight is less than or equal to a given limit B and the total value is as large as possible. Find the maximum total value. (Note that each item can be only chosen once).

Input

The first line contains the integer T indicating to the number of test cases.

For each test case, the first line contains the integers n and B.

Following n lines provide the information of each item.

The i-th line contains the weight w[i] and the value v[i] of the i-th item respectively.

1 <= number of test cases <= 100

1 <= n <= 500

1 <= B, w[i] <= 1000000000

1 <= v[1]+v[2]+...+v[n] <= 5000

All the inputs are integers.

Output

For each test case, output the maximum value.

Sample Input

1
5 15
12 4
2 2
1 1
4 10
1 2

Sample Output

15

 

I found the code of two backpacks and typed it. The first one was too much TEL because of repeated searches, and the second one was bursting because the array space was too large.

TEL code

 1 int n, W;
 2 int w[MAX_N], v[MAX_N];
 3 
 4 int rec(int i, int j) {
 5     int res;
 6     if (i == n) {
 7         res = 0;
 8     } else if (j < w[i]) {
 9         res = rec(i + 1, j);
10     } else {
11         res = max(rec(i + 1, j), rec(i + 1, j - w[i]) + v[i]);
12     }
13     return res;
14 }
15 
16 void solve() {
17     printf("%d\n", rec(0, W));
18 }

 

The above code can be optimized, and the location of the trial production will no longer be queried, but an array of dp[MAX_N][MAX_W] needs to be opened. Because the value range of MAX_W is too large, this method cannot be used to answer this question. .

 

optimize code

 1 int dp[MAX_N][MAX_W];
 2 
 3 int rec(int i, int j) {
 4     if (dp[i][j] >= 0) 
 5         return dp[i][j];
 6     
 7     int res;
 8     if (i == n) {
 9         res = 0; 
10     } else if (j < w[i]) {
11         res = rec(i+1, j);
12     } else {
13         res = max(rec(i+1, j), rec(i+1, j-w[i]) + v[i]);
14     }
15     return dp[i][j] = res;
16 }
17 
18 void solve() {
19     memset(dp, -1, sizeof(dp));
20     printf("%d\n", rec(0, W));
21 }

 

Oversized backpack, because the number of backpacks in this problem is too large, and the algorithm complexity of using an oversized backpack is O(2^n) level, so this problem cannot be solved with an oversized bag. Oversized backpacks are only suitable for situations where the number of other fraternities is small but the weight and value are high.

 

Oversized Backpack Code:

 1 typedef long long ll;
 2 
 3 int n;
 4 ll w[MAX_N], v[MAX_N];
 5 ll W;
 6 
 7 pair<ll, ll> ps[1 << (MAX_N / 2)];
 8 
 9 void solve() {
10     int n2 = n / 2;
11     for (int i = 0; i < 1 << n2; i++) {
12         ll sw = 0, sv = 0;
13         for (int j = 0; j < n2; j++) {
14             if (i >> j & 1) {
15                 sw += w[j];
16                 sv += v[j];
17             }
18         }
19         ps[i] = make_pair(sw, sv);
20     }
21     
22     sort(ps, ps + (1 << n2));
23     int m = 1;
24     for (int i = 1; i < 1 << n2; i++) {
25         if (ps[m-1].second < ps[i].second) {
26             ps[m++] = ps[i];
27         }
28     }
29     
30     ll res = 0;
31     for (int i = 0; i < 1 << (n-n2); i++) {
32         ll sw = 0, sv = 0;
33         for (int j = 0; j < n - n2; j++) {
34             if (i >> j & 1) {
35                 sw += w[n2+j];
36                 sv += v[n2+j];
37             }
38         }
39         if (sw <= W) {
40             ll tv = (lower_bound(ps, ps+m, make_pair(W - sw, INF)) - 1) -> second;
41             res = max(res, sv + tv);
42         }
43     }
44     printf("%d\n", res);
45 }

 

answer:

The maximum mass is 1000000000, the array is definitely not enough.

However, the total value is only 5000. We use the value as the axis to open up a one-dimensional array to record the remaining loadable mass. The latter approach is exactly the same as the 01 backpack.

 

AC code

 1 #include<cstdio>
 2 #include<cstring>
 3 int main(){
 4     int weight[5001], t, i, j, n, B, max_value, w, v;
 5     scanf("%d", &t);
 6 
 7     while (t--){
 8         scanf("%d%d", &n, &B);
 9         memset(weight, 0, sizeof(weight));
10         weight[0] = B, max_value = 0;
11 
12         for (j = 0; j < n; ++j){
13             scanf("%d%d", &w, &v);
14             for (i = max_value; i >= 0; --i){
15                 if (weight[i] - w > weight[i + v]) weight[i + v] = weight[i] - w;
16             }
17             for (i = max_value + 1; i <= 5000; ++i) if (weight[i]) max_value = i;
18         }
19 
20         printf("%d\n", max_value);
21     }
22     return 0;
23 }

 

Summary: Through this question, I also realized that my understanding of the template code is far from enough, so this situation occurs.

come on! ! ! ! ! ! ! ! ! !

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324653846&siteId=291194637