背包问题规律总结

注意点:搞不清楚就写出dp数组
01背包问题,选不选该种物品``
for i in  range(1,len(nums)+1):
  for j in range(W+1):
    if j>=w[i]:
      dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])
    else:
      dp[i][j] = dp[i-1][j]

压缩数组后
由于dp[i][j]需要dp[i-1][j]的数据,dp[i-1][j]不可被覆盖,如果从后往前遍历的话,dp[i-1][j]不会被覆盖

for i in range(len(nums)):
  for j in  range(W,-1,-1):
    if j>=w[i]:
      dp[j] = max(dp[j],dp[j-w[i]]+v[i])

完全背包问题:
简单思路(也是处理多重背包的思路,将W//(w[i])改为多重背包的上限即可),将其转化为01背包问题,给物品属性加倍作为新的物品,要求不超过总重量

for i in range(len(nums)):
  for j in  range(W,-1,-1):
    for k in range(1,W//(w[i])):
      dp[j] += dp[j-k*w[i]]

优化思路,选不选取该个物品
dp[i][j] = dp[i-1][j] + dp[i][j-w[i]]
压缩数组后,由于dp[i][j-w[i]]需要被覆盖,dp[i-1][j]不可被覆盖,如果从前往后遍历刚好可以满足上述要求

for i in range(len(nums)):
  for j in  range(1,W+1):
      if j-w[i]>=0:
        dp[j] += dp[j-w[i]]

有序完全背包问题:
以组合中最后一个选中的数字为准,即可满足有序条件,所以需要将重量的循环拿到外边

for j in  range(1,W+1):
  for i in range(len(nums)):
      if j-w[i]>=0:
        dp[j] += dp[j-w[i]]
posted @ 2021-08-17 12:00  Marklong  阅读(56)  评论(0编辑  收藏  举报