01 backpack problem summary

Source: Internet
Author: User

In the past two days, I made a question about the 0th backpack.

First, for the most basic 01 backpack problem, the transfer equation is DP [I] [J] = max {DP [I-1] [J], DP [I-1] [J-cost [I] + W [I]}

Indicates that the I-th item is considered. When the size is J, there are two policies. The first is not to select this item, and the second is to select this item, select an optimal policy among the two policies

Complexity O (VN)

 

Pseudocode

For I = 1 to n

For V = 0 to V

If (V> = cost [I])

DP [I] [v] = max (DP [I-1] [v], DP [I-1] [V-cost [I] + W [I])

 

If you use a rolling array to compress space:

 

For I = 1 to n

For v = V to 0

If (V> = cost [I])

DP [v] = max (DP [v], DP [V-cost [I] + W [I])

 

Note that after the capacity starts from large to small, it can be represented by a one-dimensional array. Of course, it is correct that the capacity of all items is correct.

 

For the 01 backpack problem, each item is considered only once, and each item can only be added once, which is exactly why V needs to be large to small in the second cycle, because when the item capacity is correct, the large size is determined by the small size. If the item is pushed from an early age, it may be added to the backpack for multiple times.

In one-dimensional code, DP [v] is equivalent to DP [I-1] [v] before being updated. If we start to push the capacity from large to small, let's set V1> V2, when we update V1, V2 has not been updated, indicating DP in two-dimensional [I-1] [v], once updated, it indicates DP [I] [v, if we push from small to large, this may happen: DP [V2] is updated once by item I, when DP [V1] is updated again, DP [V2] and backpack I are updated. In this way, item I is installed twice in the information saved by DP [V1, this is different from the 01 backpack definition.

 

Of course, if the item capacity is negative at this time, we must push V from small to large. The truth is the same.

 

Poj 3132 sum of different primes

Evaluate the number n of solutions composed of k different prime numbers, where 5 = 2 + 3 and 5 = 3 + 2 are the same, that is, the order is not considered.

This question can be converted into a 01-pack solution, where n is less than or equal to 1120, k <= 14. We can first create a table to display the prime number in 1120, and then regard the 187 prime number as 187 items, then their sum is regarded as capacity,

That is, 1 <= n <= 187,1 <= V <= 1120

However, this question has an additional dimension limit, that is, the limit on the number of loaded items. It doesn't matter. Just do it by recursion.

DP [I] [J] [k] indicates the number of solutions where J prime numbers in the first I prime numbers constitute and sum K, DP [I] [J] [k] = sum {DP [I-1] [1 .. j-1] [k-prime [I]

One-dimensional I can be removed after the space is compressed, but K needs to be enumerated from large to small, because repeated prime numbers cannot be used!

 

Code:

# Include <iostream> <br/> # include <memory. h> <br/> # include <string> <br/> # include <cstdio> <br/> # include <algorithm> <br/> # include <math. h> <br/> # include <stack> <br/> # include <queue> <br/> # include <vector> <br/> # include <map> <br /> using namespace STD; <br/> bool flag [1200]; <br/> int prime [1200], p_num; <br/> int DP [15] [1121]; <br/> void Init () <br/> {<br/> memset (flag, false, sizeof (FLAG); <br/> flag [1] = true; <br/> P_num = 0; <br/> for (INT I = 2; I <= 1120; I ++) <br/>{< br/> If (! Flag [I]) <br/> prime [p_num ++] = I; <br/> for (Int J = I * 2; j <= 1120; J + = I) <br/>{< br/> flag [J] = true; <br/>}< br/> int main () <br/>{< br/> int I, J, K; <br/> Init (); <br/> memset (DP, 0, sizeof (DP); <br/> // cout <p_num <Endl; <br/> DP [0] [0] = 1; <br/> for (I = 0; I <p_num; I ++) <br/> {<br/> for (k = 1120; k> = 0; k --) <br/> {<br/> for (j = 14; j> = 1; j --) <br/> {<br/> If (k> = prime [I] & DP [J-1] [k-prime [I]) <br/> DP [J] [k] + = DP [J-1] [k- Prime [I]; <br/>}< br/> while (scanf ("% d", & I, & J )! = EOF) <br/>{< br/> if (I + J = 0) <br/> break; <br/> int ans = 0; <br/> printf ("% d/N", DP [J] [I]); <br/>}< br/> return 0; <br/>}

 

Poj 2184 cow Exhibition

It can also be converted into a 01 backpack, but this question requires some changes and regards s as the capacity, if F is regarded as a value, DP [I] [J] = the maximum value of F when the sum of S is J, and the s that meet the conditions and their corresponding F are enumerated, because I may be negative, you need to increase the del value translation, of course, you can also compress it into one-dimensional, but you need to consider the case where the fi is greater than 0 and less than 0, make sure that I have only been added for one time. You can set the left and right boundary Optimization for I. I ran from over 200 to ms. For details, refer to: limit: # Include <iostream> <br/> # include <memory. h> <br/> # include <string> <br/> # include <cstdio> <br/> # include <algorithm> <br/> # include <math. h> <br/> # include <stack> <br/> # include <queue> <br/> # include <vector> <br/> # include <map> <br /> using namespace STD; <br/> const int max = 200005; <br/> const int del = 100000; <br/> const int INF = 1 <30; <br/> int DP [Max]; <br/> int main () <br/> {<br/> int I, j, k, n, S, F, l, R; <br/> for (I = 0; I <= 200000; I ++) <br/> DP [I] =-INF; <br/> DP [0 + DEL] = 0; <br/> L = 0; <br/> r = 0; <br/> scanf ("% d", & N ); <br/> for (I = 0; I <n; I ++) <br/> {<br/> scanf ("% d", & S, & F); <br/> If (S <0) <br/> {<br/> for (j = L; j <= r; j ++) <br/>{< br/> K = J + DEL; <br/> If (K + S> = 0 & DP [k]! =-INF) <br/>{< br/> // cout <I <"" <K + S-del <Endl; <br/> DP [K + S] = max (DP [K + S], DP [k] + F ); <br/>}< br/> L + = s; <br/>}< br/> else <br/> {<br/> for (j = r; j> = L; j --) <br/>{< br/> K = J + DEL; <br/> If (K + S <= 200000 & DP [k]! =-INF) <br/>{< br/> // cout <I <"" <K + S-del <Endl; <br/> DP [K + S] = max (DP [K + S], DP [k] + F ); <br/>}< br/> r + = s; <br/>}< br/> int ans = 0; <br/> for (I = 0 + DEL; I <= 200000; I ++) <br/> {<br/> If (DP [I]> = 0) <br/> ans = max (ANS, I + dp [I]); <br/>}< br/> printf ("% d/N ", ans-del); <br/> return 0; <br/>}Poj 1837 balance is similar to 2184, but this question is about the number of solutions, similar to 3132, we first define the state equation as the number of solutions when DP [I] [J] is the first heavy weight and the torque is J, DP [I] [J] = sum {DP [I-1] [J-pos [k]}, 1 <= k <= m, M is the number of hooks, if POS [k] is the position of the K hook, can this problem be compressed? The answer is no, because different hooks need to be enumerated in the same dimension I during the question transfer. It is better whether POS [k] is correct or not, the POS [k] is positive when it is negative. It is possible to load the I-th hook into the backpack multiple times, let's share the experience with the above two questions. The final result is DP [N] [0 + DEL].

Code: # Include <iostream> <br/> # include <memory. h> <br/> # include <string> <br/> # include <cstdio> <br/> # include <algorithm> <br/> # include <math. h> <br/> # include <stack> <br/> # include <queue> <br/> # include <vector> <br/> # include <map> <br /> using namespace STD; <br/> const int del = 7500; <br/> int DP [21] [del * 2 + 5], W [100], POS [100]; <br/> int main () <br/> {<br/> int I, j, k, n, m; <br/> while (scanf ("% d", & M, & N )! = EOF) <br/>{< br/> for (I = 1; I <= m; I ++) <br/> scanf ("% d ", & Pos [I]); <br/> for (I = 1; I <= N; I ++) <br/> scanf ("% d ", & W [I]); <br/> memset (DP, 0, sizeof (DP); <br/> DP [0] [0 + DEL] = 1; <br/> for (I = 0; I <n; I ++) <br/> {<br/> for (k =-7500; k <= 7500; k ++) <br/>{< br/> If (! DP [I] [K + DEL]) <br/> continue; <br/> for (j = 1; j <= m; j ++) <br/> {<br/> DP [I + 1] [K + W [I + 1] * POS [J] + DEL] + = DP [I] [K + DEL]; <br/>}< br/> printf ("% d/N", DP [N] [0 + DEL]); <br/>}< br/> return 0; <br/>} 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.