赞
踩
第一:0/1背包问题是一个什么样的问题?
0/1背包问题是一个经典的动态规划问题。它的问题描述是:给定一组物品,每个物品有一个重量和一个价值,还有一个背包的容量限制。需要选择一些物品放入背包中,使得放入背包的物品的总重量不超过背包的容量限制,同时使得放入背包的物品的总价值最大。
问题描述: 有n个物品,每个物品的重量分别为w1, w2, ..., wn,价值分别为v1, v2, ..., vn,背包的最大承重为W。求解如何选择物品使得物品的总价值最大化,且总重量不超过背包的承重。
解决方案:
v代表value价值,w代表weight重量
第二:0/1背包问题示例:
下面是一个简单的Python实现:
- def knapsack(weights, values, capacity):#定义一个背包有参函数
- n = len(weights) # 物品的数量,通过重量这个列表得到物品的数量。
-
- # 这段代码创建了一个二维数组 dp,其大小为 (n+1) × (capacity+1),并且初始化所有元素为0。
- dp = [[0] * (capacity + 1) for _ in range(n + 1)]
-
- # 动态规划的过程
- for i in range(1, n + 1):
- for j in range(1, capacity + 1):
- # 如果当前物品的重量大于背包的容量限制,则不选择当前物品
- if j < weights[i-1] :
- dp[i][j] = dp[i-1][j]
- else:
- # 否则,选择当前物品或者不选择当前物品,取价值最大的情况
- dp[i][j] = max(dp[i-1][j], values[i-1] + dp[i-1][j-weights[i-1]])
-
- # 返回最优解(即最大价值)
- return dp[n][capacity]
- weights = [2, 3, 4, 5] # 物品的重量
- values = [3, 4, 5, 6] # 物品的价值
- capacity = 8 # 背包的容量限制
-
- result = knapsack(weights, values, capacity)
- print("最大价值:", result)
如上:
已知状态转移方程
判别条件 | 结果 | 原因 |
j < weights[i-1] | dp[i][j] = dp[i-1][j] | 装不下 |
j >= weights[i-1] | dp[i][j] = max(dp[i-1][j], values[i-1] + dp[i-1][j-weights[i-1]]) | 装得下 |
运行结果为:
第二个举例展示:
- w=[3,2,1,4,5]
- v=[25,20,15,40,50]
- n=len(w)
- capacity=6
- dp = [[0] * (capacity + 1) for _ in range(n +1 )]
- for i in range(1,n+1):
- for j in range(1,capacity+1):
- if j<w[i-1]:
- dp[i][j]=dp[i-1][j]
- else :
- dp[i][j]=max(dp[i-1][j-1],v[i-1]+dp[i-1][j-w[i-1]])
- print("最大价值为:",dp[i][j])
请注意i为物品的实时数量,j为实时容量。
j为0表示此时可装入物品重量为0,i为0表示可装入物品数量为0。
运行结果展示:
这个实现的时间复杂度为O(n*capacity),其中n是物品的数量,capacity是背包的容量限制。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。