和0-1背包的差别在于物品可以重复使用无限多次,所以在遍历背包的时候需要正序遍历,重复使用前面的状态
完全背包问题的遍历顺序 先物品还是先背包都可以,因为不影响状态的更新
先物品再背包是组合数,物品的顺序是不变的
先背包再物品是排列数,物品的顺序会改变
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
## dp数组的含义,从i个物品中任取,装满amount的背包有多少种
## 本题的coin 价值和重量相同
dp = [0] * (amount + 1)
dp[0] = 1
for i in range(len(coins)):
for j in range(amount + 1):
if j >= coins[i]:
dp[j] += dp[j - coins[i]]
return dp[amount]
计算装满背包有多少种类的问题的递推公式就是
dp[j] += dp[j - weight[i]]
因为装满j的背包的种类由所有装满j-weight[i]背包的种类求和得到,因为所有装满j-weight[i]的背包都可以和i组成装满j的背包
class Solution:
def combinationSum4(self, nums: List[int], target: int) -> int:
dp = [1] + [0]* (target)
for j in range(target + 1):
for i in range(len(nums)):
if j >= nums[i]:
dp[j] += dp[j - nums[i]]
return dp[target]
因为存在顺序不同的序列,实际上求排列的数目,就是先遍历背包再遍历物品