题目描述:有N个物品,每个物品的重量是wi ,每个物品的价值是vi 。 求解当背包容量为W时,能获得的最大价值,并输出获得最大价值时每种物品是否在背包内 数据范围 0 < n <= 30 重量、价值、背包容量均为正整数 。输入: 第一行两个数,N和W,N表示物品的个数,W表示容量限制 接下来N行,每行两个数,分别是wi和vi,分别表示第i个物品的重量和价值 。输出: 第一行一个数,为最大价值 第二行N个数,依次表示各个物品的是否放在背包里(0表示不放,1表示放),如果有多种方案,取字典序
时间: 2023-09-21 17:06:21 浏览: 368
这道题可以使用动态规划来解决。定义一个二维数组dp[i][j]表示前i个物品放入容量为j的背包中能获得的最大价值。则有以下状态转移方程:
- 如果不放第i个物品,则dp[i][j] = dp[i-1][j]
- 如果放第i个物品,则dp[i][j] = dp[i-1][j-wi] + vi
取两者的最大值即可,即dp[i][j] = max(dp[i-1][j], dp[i-1][j-wi] + vi)。
最后,从dp[n][w]开始,根据状态转移方程倒推出每个物品是否在背包里,具体实现可以参考下面的代码:
```python
n, w = map(int, input().split())
# 初始化dp数组
dp = [[0] * (w+1) for _ in range(n+1)]
# 读入物品信息
items = [(0, 0)]
for i in range(n):
wi, vi = map(int, input().split())
items.append((wi, vi))
# 动态规划求解最大价值
for i in range(1, n+1):
for j in range(1, w+1):
if j >= items[i][0]:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-items[i][0]] + items[i][1])
else:
dp[i][j] = dp[i-1][j]
# 输出最大价值
print(dp[n][w])
# 输出每个物品是否在背包里
chosen = [0] * (n+1)
j = w
for i in range(n, 0, -1):
if dp[i][j] > dp[i-1][j]:
chosen[i] = 1
j -= items[i][0]
for i in range(1, n+1):
print(chosen[i], end=" ")
```
时间复杂度为O(nw),空间复杂度为O(nw)。由于n的范围比较小,本题可以通过此方法AC。
阅读全文