描述
给定整数组nums, 整数W, 求nums有几种方案可以凑成W。数据可以使用多次
递归解法:
元素选择:选可以选择1词或者多次 ```python def backtrack(w: [], W: int, i: int) -> int:
base case
if i == len(w) or W == 0:
if W == 0:return 1return 0
else:if w[i] <= W:return sum((backtrack(w, W - w[i], i), # 选了这次,下次可能继续选, 至少选一次backtrack(w, W, i + 1))) # 可以选但不选。 一次都不选else:return backtrack(w, W, i + 1) # 没法选
if name == ‘main‘: coins = [1, 2, 5] print(backtrack(coins, 4, 0))
<a name="ksKrK"></a>### 动态规划解法- `dp[i][j] = x` :- 状态转移:```pythondef full_package(nums, W):# dp数组初始化,dp = [[0 for j in range(W + 1)] for i in range(len(nums) + 1)]for row in range(len(nums) + 1): # 重量为0时, 唯一方案就是不用选择任何数,dp[row][0] = 1for i in range(1, len(nums) + 1): # 物品for j in range(1, W + 1): #if nums[i - 1] <= j: #dp[i][j] = dp[i][j - nums[i - 1]] + dp[i - 1][j]else:dp[i][j] = dp[i - 1][j]for row in dp:print(row)if __name__ == '__main__':coins = [1, 2, 5]full_package(coins, 5)
总结
- 元素可多选的处理
- 状态转移和自顶向下的关联
- 有时候, 数组有序性会将重复情况排除
