Leetcode Link: 无,算法课上的问题
题目
arr 是货币数组,其中的值都是正数。再给定一个正数 aim。
每个值都认为是一张货币
即便是值相同的货币也认为每一张都是不同的,
返回组成 aim 的方法数
例如:arr={1,1,1}, aim=2
第0个和第1个能组成2,第1个和第2个能组成2,第0个和第2个能组成2
一共就3种方法,所以返回3
从暴力递归到动态规划
典型的从左到右的尝试模型,从左到右尝试 arr
子问题可以是返回[idx… n]上凑成 rest 的方法数
每个子问题只有如下两种情况
- 要当前位的凑
- 不要当前位的凑
def main(arr, aim):
return process(arr, 0, aim)
def process(arr, idx, rest):
if rest == 0:
return 1
if rest < 0 or (rest > 0 and idx == len(arr)):
return 0
p1 = process(arr, idx+1, rest)
p2 = process(arr, idx+1, rest-arr[idx])
return p1 + p2 动态规划
显然只有两个可变参数
代码待确认
def main(arr, aim):
dp = [[0 for _ in range(aim+1)] for _ in range(len(arr)+1)]
for i in range(len(arr)):
dp[i][0] = 1
for i in range(len(arr)-1, -1, -1):
for j in range(aim+1):
dp[i][j] = process(arr, idx+1, rest)
if rest-arr[idx] >= 0:
dp[i][j] += process(arr, idx+1, rest-arr[idx])
return dp[0][aim]