版权声明:原创部分都是自己总结的,如果转载请指明出处。觉得有帮助的老铁,请双击666! https://blog.csdn.net/qq_36387683/article/details/81948210
279. 凑 N 分钱的方案数
给你无限多个的 25 分,10 分,5 分和 1 分的硬币。问如果要凑出 n
分钱有多少种不同的方式?
样例
给出 n = 11
11 = 1 + 1 + 1... + 1
= 1 + 1 + 1 + 1 + 1 + 1 + 5
= 1 + 5 + 5
= 1 + 10
返回 4
。
class Solution:
"""
@param n: An integer
@return: An integer
"""
'''
#暴力递归 TLE
def waysNCents(self, n):
# write your code here
arr = [1, 5, 10, 25]
if n < 0:
return 0
return self.process1(arr, 0, n)
def process1(self, arr, index, n):
res = 0
if index == len(arr):
res = 1 if n == 0 else 0
else:
i = 0
while arr[index] * i <= n:
res += self.process1(arr, index+1, n - arr[index] * i)
i += 1
return res
'''
'''
#记忆化搜索 TLE
def waysNCents(self, n):
# write your code here
arr = [1, 5, 10, 25]
if n < 0:
return 0
me = [[0] * (n+1) for i in range(5)]
return self.process2(arr, 0, n, me)
def process2(self, arr, index, n, me):
res = 0
if index == len(arr):
res = 1 if n==0 else 0
else:
mapValue = 0
i = 0
while arr[index] * i <= n:
mapValue = me[index+1][n-arr[index]*i]
if mapValue != 0:
res += 0 if mapValue == -1 else mapValue
else:
res += self.process2(arr, index+1, n-arr[index]*i , me)
i += 1
me[index][n] = -1 if res == 0 else res
return res
'''
'''
#动态规划 TLE
def waysNCents(self, n):
# write your code here
arr = [1, 5, 10, 25]
if n < 0:
return 0
dp = [[0] * (n+1) for _ in range(len(arr))]
#组成钱数为0的方法只有一种
for i in range(len(arr)):
dp[i][0] = 1
#矩阵第一行,表示第一种面值,能够组成钱数的方法
k = 1
while arr[0] * k <= n:
dp[0][arr[0]*k] = 1
k += 1
num = 0
for i in range(1, len(arr)):
for j in range(1, n+1):
num = 0
#用k张arr[i]货币,剩下的钱用比他面值小的钱arr[0..i-1]组成,方法数为dp[i][j] = dp[i-1][j-arr[i]*k]
k = 0
while j - arr[i]*k >= 0:
num += dp[i-1][j-arr[i]*k]
k += 1
dp[i][j] = num
return dp[-1][n]
'''
'''
#动态规划 O(n*aim)
#dp[i][j] = dp[i-1][j-arr[i]*k],第一种情况的方法数为dp[i-1][j];从2到第K种情况的累加值其实就是dp[i-1][j-arr[i]]的值
def waysNCents(self, n):
# write your code here
arr = [1, 5, 10, 25]
if n < 0:
return 0
dp = [[0] * (n+1) for _ in range(len(arr))]
#组成钱数为0的方法只有一种
for i in range(len(arr)):
dp[i][0] = 1
#矩阵第一行,表示第一种面值,能够组成钱数的方法
k = 1
while arr[0] * k <= n:
dp[0][arr[0]*k] = 1
k += 1
num = 0
for i in range(1, len(arr)):
for j in range(1, n+1):
#可以完全用前一种面值组成
dp[i][j] = dp[i-1][j]
#加上用自己的面值组成
dp[i][j] += dp[i][j - arr[i]] if j-arr[i] >= 0 else 0
return dp[-1][n]
'''
#动态规划 空间压缩 O(n*aim) S(aim)
def waysNCents(self, n):
# write your code here
arr = [1, 5, 10, 25]
if n < 0:
return 0
dp = [0] * (n+1)
#面值arr[0]可以组成的钱数
k=0
while arr[0] * k <= n:
dp[arr[0] * k] = 1
k += 1
for i in range(1, len(arr)):
for j in range(1, n+1):
dp[j] += dp[j-arr[i]] if j-arr[i] >= 0 else 0
return dp[-1]