01 Illustration of backpack space optimization, complete backpack time optimization

01 backpack space optimization

When learning the 01 backpack, there will be such a state transition equation:

约定:
dp[i][j]表示在0~i下标物品中选取,在总金额不超过j的情况下获得的最大价值
v[i]表示第 i 下标的物品的价值

dp[i][j] = max(dp[i-1][j], dp[i-1][j-v[i]]+v[i]);

dp[i-1][j]Corresponding to items that do not select [i subscript]
dp[i-1][j-v[i]]+v[i]Corresponding to items that do not select [i subscript]

You can write a recursive formula quickly

maxPrice表示考虑的最大总金额
共有 0~n-1 下标共n件物品

for(int i=0; i<n; i++)
	for(int j=0; j<=maxPrice; j++)
		dp[i][j] = max(dp[i-1][j], dp[i-1][j-v[i]]+v[i]);

It can be found that the answer of the current grid is only 上一行0~j下标的格子relevant.
Insert picture description here
Then we only need to save one row, and the problem comes from the previous row j and the previous area . We must let j be updated in a decreasing form to ensure that we can get the previous row. The value in front of (because j is decreasing and updating, the front is the old value, we just need the old value of the previous line)

FIG: Blue performance of the new updated value, the old red line value, that is, considering the subscript 0~i-1case
Insert picture description here
can then be transferred in a simplified state space

for(int i=0; i<n; i++)
	for(int j=maxPrice; j>=0; j--)
		dp[j] = max(dp[j], dp[j-v[i]]+v[i]);

Full backpack time optimization

The complete backpack is similar to the 01 backpack, but each item can be selected countless times, then you can still quickly write the state transition based on the 01 backpack

约定:
dp[i][j]表示在0~i下标物品中选取,在总金额不超过j的情况下获得的最大价值
共有 0~n-1 下标共n件物品
maxPrice表示考虑的最大总金额
v[i]表示第 i 下标的物品的价值
k表示第i下标的物品,选取k件

for(int i=0; i<n; i++)
	for(int j=0; j<=maxPrice; j++)
		for(int k=0; j-k*v[i]>=0; k++)
			dp[i][j] = max(dp[i-1][j], dp[i-1][j-k*v[i]]+k*v[i]);

Enumerate the possibility of selecting the i-th index item, and then do the 01 backpack multiple times to get the maximum result, but this brings an increase in time overhead. Is there a way to remove the k cycle?

[In 0~ithe subscript items selected, the maximum value obtained in the case of a total amount not to exceed j], in fact, the problem may think:

We can take the same item countless times, then the problem becomes:

  1. [In 0~i-1the subscript items selected, the maximum value obtained in the case of a total amount not to exceed j]
  2. [In 0~ithe subscript items selected, the maximum value obtained in the case of a total amount not to exceed jv [i]] of that attempt multiple-choice one

Question 1 is the value of the previous line, no problem, question 2, is the value on the right of this line, because j is updated incrementally, we quickly found that the best answer to question 2 has just been done , this line On the left, then we can quickly optimize

Suppose the solution of problem 1 is the red area, and the solution of problem 2 is the yellow area
Insert picture description here

约定:
dp[i][j]表示在0~i下标物品中选取,在总金额不超过j的情况下获得的最大价值
共有 0~n-1 下标共n件物品
maxPrice表示考虑的最大总金额
v[i]表示第 i 下标的物品的价值

for(int i=0; i<n; i++)
	for(int j=0; j<=maxPrice; j++)
		dp[i][j] = max(dp[i-1][j], dp[i][j-v[i]]+v[i]);

How to enumerate k? That is, how to ensure that multiple items are selected?
dp[i][j-v[i]]The value of, defined by the dp array, is already the result of considering selecting multiple i items, and all we have to do is try to add an i item, based on the already optimal answer (may choose k items), try to increase An i item to see if it will get a bigger result

It can also be based on the space optimization of the 01 backpack. The code for space optimization is given here, and this code is very similar to the space optimization of the 01 backpack, except that the direction of the j loop is sent to change.

for(int i=0; i<n; i++)
	for(int j=0; j<=maxPrice; j++)
		dp[j] = max(dp[j], dp[j-v[i]]+v[i]);
Published 262 original articles · won 11 · 10 thousand views

Guess you like

Origin blog.csdn.net/weixin_44176696/article/details/105209974