Nine Lectures on Backpacks (2)-Complete Backpack Problem

Nine Lectures on Backpacks (2)-Complete Backpack Problem

Refer to the famous Nine Lectures on Backpacking, which can be downloaded here , the 01 Backpack Problem in the previous article

1.1 problem

There are Nkinds of goods and capacity of a Vbackpack, each item has unlimited available member , into the first icost items is C i C_iCi, The value obtained is W i W_iWi. Find out which items to pack into the backpack to maximize the overall value.

1.2 Problem solving ideas

The only difference between a complete backpack and a 01 backpack is whether an item can be selected multiple times?

Knowing this difference, in fact, if you think about it carefully, you can completely convert the backpack problem into a 01 backpack, because the capacity V is limited, for a single item C i C_iCiIn other words, you can only put it like ⌊ V / C i ⌋ \left \lfloor V/C_i\right \rfloorV/Ci pieces, so we only need to consider the complete backpack problem as having⌊ V / C 1 ⌋ \left \lfloor V/C_1\right \rfloorV/C1 itemsC 1 C_1C1、有 ⌊ V / C 2 ⌋ \left \lfloor V/C_2\right \rfloor V/C2 itemsC 2 C_2C2、…、 ⌊ V / C N ⌋ \left \lfloor V/C_N\right \rfloor V/CN itemsCN C_NCNThe 01 backpack problem will do. But the total complexity at this time can be considered as O (NV ∑ VC i) O(NV\sum \cfrac{V}{C_i})O ( N VCiV) , this complexity is a bit high~

Furthermore, we actually have a more efficient conversion method. Using binary thinking, we can disassemble the i-th item into a cost of C i 2 K C_i2^KCi2K , the value isW i 2 k W_i2^kWi2k number of items, where k takes 1 toC i 2 k ≤ V C_i2 ^Ci2kThe largest integer of V (in fact, k can take the cost of all i items and an integer less than V), and then the time complexity can be optimized toO (NV log (⌊ V / C 2 ⌋)) O(NVlog(\left \lfloor V/C_2\right \rfloor))O ( N V l o g ( V / C2 ) ) again. A lot lower than before~

Of course, the most nb solution is not the hhh mentioned above. When solving the 01 knapsack problem, vv is required.v starts fromV, V − 1,.., 0 V, V-1,..., 0in descending orderV ,V1,..,0 calculatedp [v] dp [v]d p [ v ] , the decrement calculation of v is to ensure the statedp [v] dp[v]d p [ v ] is derived from theprevious round recursively. In fact, it is toensure that an item is selected only once, but now it is allowed to be selected multiple times. Isn’t it beautiful~ It’s very simple, let v increment to calculate dp[v ] Yes, please refer to the following pseudo code:

dp[0...V]0
for i ← 1 to N  // 依次遍历N件物品
	for v ← Ci to V // 能装下当前物品的背包使用状态方程
		dp[v] ← max{
    
    dp[v], dp[v-Ci]+Wi}

So at this time the time complexity of the problem has been reduced to O (NV) O(NV)O ( N V ) , seconds~

But the constant optimization in the 01 backpack does not exist in the complete backpack~

A simple and effective optimization, if two items i, j satisfy C i <C j C_i \lt C_jCi<Cj并且 W i ≥ W j W_i \ge W_j WiWj, Then you can directly remove the item j directly, this process can be in O (N 2) O(N^2)O ( N2 )The time complexity is not very high. If you are stuck in time, you can try this simple optimization~

1.3 Sample code

I'm too lazy to write ~ You have to create your own data, similar to the 01 backpack problem code

1.4 Actual combat stage

Do a few questions and it will be clear! !

Luogu P1616 Crazy Medicine Collection

Title description :

Li Yuxiang is a gifted child. His dream is to become the greatest physician in the world. For this reason, he wanted to worship the most prestigious physician nearby as his teacher. In order to judge his aptitude, the doctor presented him with a difficult problem. The doctor took him to a cave full of herbs and said to him: "My child, there are some different types of herbs in this cave. It takes some time to pick each one, and each one has its own value. I will Give you a period of time during which you can gather some herbs. If you are a smart kid, you should be able to maximize the total value of the herbs you gather."

If you are LiYuxiang, can you complete this task?

The difference between this question and the original question:

  1. Each herb can be picked wildly without restriction .

  2. The types of medicine are dazzling, and the time for collecting medicine is so long! The master was waiting for the chrysanthemum to thank!

Please refer to the original question website for specific input and output formats and samples~


This is a typical complete knapsack problem. It can be written directly according to the above ideas, but the amount of data in this question is relatively large. Pay attention to the long longtype of dp array used , and dynamically generate the array to prevent memory explosion, and the STL is too Slowly use malloc

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main() {
    
    
	ios::sync_with_stdio(false), cin.tie(NULL);
	// 静态数组会爆内存
	//int V[N] = { 0 }, C[N] = { 0 }, t, m;
	//long long dp[N] = { 0 };

	int t, m;
	cin >> t >> m;
	int* V = (int*)malloc(m * sizeof(int));
	int* C = (int*)malloc(m * sizeof(int));
	long long* dp = (long long*)malloc((t+1) * sizeof(long long));
	// STL太慢了
	//vector<int> V(m);
	//vector<int> C(m);
	//vector<long long> dp(t+1);
	for (int i = 0; i < m; i++) {
    
    
		cin >> C[i] >> V[i];
	}
	for (int i = 0; i < m; i++) {
    
    
		for (int j = C[i]; j <= t; j++) {
    
    
			dp[j] = max(dp[j], dp[j - C[i]] + V[i]);
		}
	}
	cout << dp[t] << endl;
	free(V);
	free(C);
	free(dp);
	return 0;
}

Submit result:

07Kye1.png

If using STL. . . .

07KWWD.png

STL is twice as much as malloc~ Of course, there is no effect if the time is not stuck here

Guess you like

Origin blog.csdn.net/weixin_44338712/article/details/109105987