LeetCode dynamic programming Theme 6: 0-1 knapsack problem on two optimization space complexity

0-1 knapsack problem talking about the question: given two items, as well as these items correspond to the value and weight. Do you have a backpack, backpack weight limit, up to ask you to take away most of the value is the number of items. This is an optimization problem with a constraint, dynamic programming to solve the problem.

Step 1: Define state.

Definition: Consider the range of the index is to put items in the backpack volume, so that the maximum value. Note: this article into consideration the capacity of the backpack, so that the maximum value.

Step 2: a state transition equation is derived. So for the following two scenarios:

1, th item is not selected, as was required;

2, the first two items are selected, as was required.

Based on the above two things: to ask, this equation is called the state transition equation.

time complexity:.
Space complexity:

In this section we optimize the space complexity.

Optimization 1: based on the first row element depends only on the element row

Since the first row of elements depends only on the element row. In theory, only the need to maintain two lines of elements can be, and to this end we have adopted a "rolling variable" approach.

Python code:

class Solution:
    def knapsack01(self, weights, values, capacity):
        '''
        一行一行填表
        # 填写第 0 行(只有 index = 0 这个物品)的时候,就看这个 index 的物品是否能放进背包
        # 如果可以放进背包,就是此时的最大价值


        :param weights:
        :param values:
        :param index:
        :param capacity:
        :return:
        '''

        l = len(weights)
        if l == 0:
            return 0
        dp = [[-1 for _ in range(capacity + 1)] for _ in range(2)]  # 我们只须要 2 行
        for i in range(capacity + 1):
            if weights[0] <= i:
                dp[0][i] = values[0]
            else:
                dp[0][i] = 0
        # 只要遇到 dp 跟 i 相关的索引的部分,都取 mod 2 的余数
        for i in range(1, l):
            for j in range(capacity + 1):
                dp[i % 2][j] = dp[(i - 1) % 2][j]
                if weights[i] <= j:
                    dp[i % 2][j] = values[i] + dp[(i - 1) % 2][j - weights[i]]
        return dp[(l - 1) % 2][-1]

Optimization 2: How will the two-dimensional reduced to one-dimensional

Rationale: behind the front-dependent, so we fill in from the right to the left, so you can use one line notice: update each row and only the elements relevant to its left, we have the space into a single line, the implementation of dynamic programming time, from the right updates to the left of it.

Python code:

class Solution:
    def knapsack01(self, weights, values, capacity):
        '''
        :param weights:
        :param values:
        :param index:
        :param capacity:
        :return:
        '''

        l = len(weights)
        if l == 0:
            return 0
        # 我们只须要 1 行
        dp = [-1 for _ in range(capacity + 1)]
        for i in range(capacity + 1):
            if weights[0] <= i:
                dp[i] = values[0]
            else:
                dp[i] = 0
        for i in range(1, l):
            for j in range(capacity, -1, -1):
                if weights[i] <= j:
                    dp[j] = max(dp[j], values[i] + dp[j - weights[i]])
        return dp[-1]

(End of this section)

Guess you like

Origin blog.csdn.net/weixin_33834679/article/details/90885280