给定数组 arr,arr 中所有的值都为正整数。每个值代表一种面值的货币,每种面值的货币只可使用一张,再给定一个整数 aim 代表要找的钱数,求换钱有多少种方法。
每种硬币都有两种可能性:
- 使用
- 不使用
暴力递归:
def process2(arr, index, aim):
if index == len(arr):
return 1 if aim == 0 else 0
return process2(arr, index + 1, aim - arr[index]) + process2(arr, index + 1, aim)
def coins2(arr, aim):
if not arr or aim < 0:
return 0
return process2(arr, 0, aim)
动态规划:
def coins5(arr, aim):
if not arr or aim < 0:
return 0
dp = [[0] * (aim + 1) for _ in range(len(arr))]
for i in range(len(arr)):
dp[i][0] = 1
# base case 只使用 arr[0] 时,由于只能使用一次,aim == arr[0]时为 1
if arr[0] <= aim:
dp[0][arr[0]] = 1
for i in range(1, len(arr)):
for j in range(1, aim + 1):
dp[i][j] = dp[i - 1][j]
dp[i][j] += dp[i - 1][j - arr[i]] if j - arr[i] >= 0 else 0
return dp[len(arr) - 1][aim]