首页 > 试题广场 >

01背包

[编程题]01背包
  • 热度指数:27032 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
已知一个背包最多能容纳体积之和为v的物品

现有 n 个物品,第 i 个物品的体积为 vi , 重量为 wi

求当前背包最多能装多大重量的物品?

数据范围:

进阶 :
示例1

输入

10,2,[[1,3],[10,4]]

输出

4

说明

第一个物品的体积为1,重量为3,第二个物品的体积为10,重量为4。只取第二个物品可以达到最优方案,取物重量为4     
示例2

输入

10,2,[[1,3],[9,8]]

输出

11

说明

两个物品体积之和等于背包能装的体积,所以两个物品都取是最优方案  
class Solution:
    def knapsack(self , V: int, n: int, vw: List[List[int]]) -> int:
        # dp[i][j]代表容量为j时在第i个物品能装的最大重量
        # 状态转移方程
        # 两种情况:
        # 1)当前物品的体积超过j,那么无法放入该物品,dp[i][j] = dp[i-1][j]
        # 2)当前物品的体积不超过j,有两种选择,取两者的较大值:
        #     不放该物品,能装的最大重量为dp[i-1][j]
        #     放入该物品,能装的最大重量为dp[i-1][j-cur_v] + cur_w
        # 观察数组可知,当体积为0或物品为0时,最大重量为0,因此第0行和第0列为0
        # 初始化二维数组
        dp = [[0]*(V+1) for i in range(n+1)]
        for i in range(1, n+1):
            for j in range(1, V+1):
                # 当前物品的体积
                cur_v = vw[i-1][0]
                # 当前物品的重量
                cur_w = vw[i-1][1]
                if cur_v > j:
                    dp[i][j] = dp[i-1][j]
                else:
                    dp[i][j] = max(dp[i-1][j], dp[i-1][j-cur_v] + cur_w)
        return dp[-1][-1]
发表于 2023-04-27 08:10:23 回复(0)
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 计算01背包问题的结果
# @param V int整型 背包的体积
# @param n int整型 物品的个数
# @param vw int整型二维数组 第一维度为n,第二维度为2的二维数组,vw[i][0],vw[i][1]分别描述i+1个物品的vi,wi
# @return int整型
#
class Solution:
    def knapsack(self , V: int, n: int, vw: List[List[int]]) -> int:
        # V 体积 。 n :物品个数 
        # 就是填表的过程。然后就出来结果了。
        # 列 是 体积的大小 
        # 行 是 物品的个数 + 1
        # 第一行 第一列 都是 0 。
        # 第 dp[row][col] 代表:在 可以装 col 的情况下,选择 前row个物品的最优解。
        # dp = [[0] * (V + 1)] * (n+1)  我这个dp数组生成的有问题,, 我。。我服了啊。用下面的就可以。打印出来长一模一样啊。
        dp = [[0 for i in range(V+1)] for j in range(n+1)]
        for row in range(1, n+1): 
            # 从左到右填表
            for col in range(1, V + 1):
                # 从上到下填表 
                # 到第row 个的时候咋选择
                # 首先看当前物品的重量是否超过当前体积。如果超过了。就填正上面的解。
                if vw[row-1][0] > col:
                    # col 是当前体积。 vw[row-1][0] 是代表到第row-1个物品。
                    # 说明不能装当前物品。当前局部最优解就是 dp[row-1][cow].
                    dp[row][col] = dp[row-1][col]
                else:
                    # 当前物品的重量小于当前的体积
                    # 这个时候有俩种情况,装当前的物品还是不装当前的物品
                    # 然后比较俩种情况,谁好选择谁

                    # 第一种情况:装当前物品,那么剩余的体积就是 col - 当前体重。
                    data_rest = col - vw[row-1][0] # 需要计算在data_rest体重的情况下,前 row-1个的最优解
                    data_1  = vw[row-1][1] + dp[row-1][data_rest]

                    # 第二种情况:不装当前物品
                    data_2  = dp[row-1][col] # 就正上方的数据

                    # 比较data_1 data_2 
                    dp[row][col] = max(data_1, data_2)
        
        return dp[-1][-1]

为啥生成dp数组打印出来一模一样,一个可以,一个不行。服了。。

发表于 2022-12-08 00:03:35 回复(2)