一.问题描述: 有 n 件物品 和 一个最多能背重量为 w 的背包。第 i 件物品的重量是weight[i],得到的价值是value[i]。每件物品只能用一次,求解将哪些物品装入背包物体的价值总和最大。 二.算法: 1).暴力思路: 每一个物体只有两种状态(取,不取),n个物体的话就有2 ^ n种状态 2).动态规划: 存放[0-i]的物体的背包容量为j的背包 使其存放物品的价值量最大的状态依赖 存放[0 - i-1]的物品的容量为j-1的背包 的状态相关 动态规划五部曲(来自--代码随想录): 1.确定dp数组含义:dp[i][j] -- 将[0,i]的物体放到容量为 j 的背包,所能达到的最大价值量 2.递推公式:dp[i][j] = 不放 i(需要判断先能不能放i) : dp[i-1][j] ; 放第 i 号物品 : dp[i-1][j-weight[i]] + value[i] 3.初始化: dp[x][0] -- 第 0 列 表示将[0,x]的物体放到容量为 0 的背包,显然价值为 0 dp[0][x] -- 第 1 行 表示将[0,0]的物体放到容量为 x 的背包,总价值 = if x >= weight[0]:dp[0][x] = value[0] else dp[0][x] = 0 4.遍历顺序: 先行后列 或 先列后行 均可(dp[i][j] 的值只与其上面 和 斜上角的值有关) 5.打印dp数组,debug print(dp) 查看是否符合题目要求 三.代码 -- python # M = 6 # 物品种类 -- 每个物品只有一个 # K = 1 # 背包空间 # value = [2,3,1,5,4,3] # 每个物品的价值 # weight = [2,2,3,1,5,2] # 每个物品的重量 value = [] weight = [] # 接收外部传来的参数 # 第一行传入M , K s1 = input("please input M and K,divide by ' ' ") M = int(s1.split()[0]) K = int(s1.split()[1]) # 第二行传入weight列表 s2 = input("please input list of weight,divide by ' ' ") s2_list = s2.split(" ") for e in s2_list: weight.append(int(e)) # 第三行传入value列表 s3 = input("please input list of value,divide by ' ' ") s3_list = s3.split(" ") for e in s3_list: value.append(int(e)) # 背包的大小不能为 0 且 物品的种类不能为 0 if K <= 0 or M <= 0: print(f"背包的空间 为小于等于0的值;放不进去任何物品") # 创建dp数组 -- 大小为 : M x (K + 1) ( M 是总物品的个数 [0 - M-1] , K 是背包的最大容量) # dp[i][j] -- 将[0,i]的物体放到容量为 j 的背包,所能包含的最大价值量 dp = [] for i in range(M): dp.append([0] * (K + 1)) # 递推公式 -- dp[i][j] = 不放 i : dp[i-1][j] ; 放第 i 号物品 : dp[i-1][j-weight[i]] + value[i] # dp[i][j] = max( dp[i-1][j] , dp[i-1][j-weight[i]] + value[i] ) # 初始化 # dp[x][0] -- 第 0 列 表示将[0,x]的物体放到容量为 0 的背包,显然价值为 0 # dp[0][x] -- 第 1 行 表示将[0,0]的物体放到容量为 x 的背包,总价值 = if x >= weight[0]:dp[0][x] = value[0] else dp[0][x] = 0 for i in range(M): dp[i][0] = 0 for i in range(K+1): if i >= weight[0]: dp[0][i] = value[0] else: dp[0][i] = 0 # 遍历dp数组 # 先遍历 行,再遍历 列(反之也可以) for i in range(1,M): for j in range(1,K+1): if j < weight[i]: # 放不下去 dp[i][j] = dp[i-1][j] else: # 可以放下去,看放不放(比较总价值量) dp[i][j] = max(dp[i-1][j] , dp[i-1][j-weight[i]] + value[i]) # 打印 print(f"dp 数组 = {dp}") print(f"容量为 {K} 的背包 所能存放的最大商品价值量 是{dp[M-1][K]}")