01 backpack Problems
There are N items and a backpack with a capacity of V. The volume of the I-th item is c [I], and the value is w [I]. Solving which items are loaded into a backpack can maximize the total value.
Basic Ideas
This is the most basic problem with a backpack. It features that each item has only one item, and you can choose to put it or not. Define the status with sub-questions: f [I] [v] indicates the first I item
Put a backpack with a capacity of v to maximize the value. The state transition equation is:
F [I] [v] = max {f [I-1] [v], f [I-1] [v-c [I] + w [I]}.
This equation is very important. Basically all the equations related to the knapsack problem are derived from it. So it is necessary to explain it in detail
Next: Put the first I items in a v-sized backpack. If you only consider the I-th item Policy (put or not put ), then it can be converted into
Problems involving items in front of the I-1. If I items are not put, then the problem is converted into the first I-1 items into the capacity of v in the backpack, the value is f [I-1] [v];
If you put the I item, then the problem is converted into the previous I-1 item into the remaining capacity v-c [I] of the backpack, at this time the biggest value is:
F [I-1] [v-c [I] + w [I].
Optimize space complexity
The time complexity and space complexity of the above methods are O (VN). The time complexity should no longer be optimized, but the space complexity can be optimized.
To O (N ). First, consider how to implement the basic idea mentioned above. It must be a main loop I = 1... N, and calculate all values of f [I] [0... V] each time. Then, if only
What if I use an array f [0... V? F [I] [v] comes from two subproblems: f [I-1] [v] and f [I-1] [v-c [I, can we ensure that when pushing f [I] [v] (that is, pushing in the I-th loop)
F [v]) is it possible to get the values of f [I-1] [v] and f [I-1] [v-c [I? In fact, this requires that f [v] be pushed in the order of V = v... 0 in each main loop, so as to ensure
F [v] f [v-c [I] saves the value of State f [I-1] [v-c [I. The pseudocode is as follows:
If the v Order is changed to the reverse order above, that is, v = 0... V is introduced by f [I] [v] by f [I] [v-c [I], which is inconsistent with the meaning of this question.
Instance
After talking about the theory, let's look at the actual example. The example below is the original question on hangdian ACM: Bone Collector. The following is my AC code:
#include<iostream>using namespace std;int main(){ int T; cin >> T; while (T--) { int N, V; int value[1001], volume[1001]; cin >> N >> V; for (int i = 0; i < N; i++) { cin >> value[i]; } for (int i = 0; i < N; i++) { cin >> volume[i]; } int f[1001] = {0}; for (int i = 0; i < N; i++) { for (int v = V; v >= volume[i]; v--) { f[v] = max (f[v], f[v-volume[i]]+value[i]); } } cout << f[V] << endl; } return 0;}
You only need to apply the given recursive formula to the above question. We need to change the following question slightly: Robberies. My AC code:
# Include <iostream> using namespace std; double max (double a, double B) {return a> B? A: B;} int main () {int T; cin> T; while (T --) {double cp; double p [10001]; // Number of bankers according to the question: N <100, but the array has not been opened to 1001. It should be the background detection data and the question size is different: int a [10001]; double f [10001]; int n; cin> cp> n; int m = 0; for (int I = 0; I <n; I ++) {cin> a [I]> p [I]; m + = a [I];} memset (f, 0, sizeof (f )); f [0] = 1; for (int I = 0; I <n; I ++) {for (int j = m; j> = a [I]; j --) {f [j] = max (f [j], f [j-a [I] * (1-p [I]);} int I; for (I = m; I> = 0; I --) {if (f [I]> = 1-cp) break ;} cout <I <endl;} return 0 ;}