您现在的位置是:首页 >技术杂谈 >day44|动态规划7-装满背包最小用多少件物品(零钱兑换,完全平方数)网站首页技术杂谈
day44|动态规划7-装满背包最小用多少件物品(零钱兑换,完全平方数)
简介day44|动态规划7-装满背包最小用多少件物品(零钱兑换,完全平方数)
70. 爬楼梯 (进阶)
之前使用斐波那契数列的方法解决过该问题,这次可以利用完全背包分析该问题。
首先先复习一下什么是完全背包: 完全背包指的是向容量一定的背包放入无限的物品,两层for循环均为正序,与此同时不同的for循环的顺序所代表的排列和组合问题是不同的。
这次可以使用完全背包的方式再分析一下该问题。
- 解题思路: 现在就是将楼梯的阶数想象成背包的容量,然后将上台阶的情况设置为物品的情况,物品的情况有1或者2,这样即可将该问题进行拆解。
dp = [0] * (n+1)
bag = [1,2]
dp[0] = 1
# 先遍历背包再遍历物品
for i in range(1,n+1):
for j in range(len(bag)):
if i - bag[j] >= 0:
dp[i] += dp[i-bag[j]]
return dp[n]
322. 零钱兑换(装满背包最小用多少件物品)
- 如果求组合数就是外层for循环遍历物品,内层for遍历背包。
- 如果求排列数就是外层for遍历背包,内层for循环遍历物品。
凑成相应数值所需要的最少的钱币数值是多少,因为是最小值,所以在初始化的时候需要用 float(‘inf’) 进行初始化。
动归五步曲:
- dp[j]:表示装满承重为j的背包最小的物品件数。
- 遍历顺序:
- 初始化:利用float(‘inf’)对dp数组进行初始化操作
- 递归函数:dp[i] = min(dp[i-coins[j]]+1,dp[i])
- 打印dp数组
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
# 凑成所需硬币的最小个数
dp = [float('inf')] * (amount+1)
# 由于取得是最小值,所以需要得到的值是
dp[0] = 0
for i in range(1,amount+1):
for j in range(len(coins)):
if i-coins[j] >= 0:
dp[i] = min(dp[i-coins[j]]+1,dp[i])
return dp[amount] if dp[amount] != float("inf") else -1
?279.完全平方数
这道题需要注意一下,因为在之前的笔试过程中出现过,但是当时没想到可以使用动态规划的方式进行求解。
思路:可以利用先遍历物品再遍历背包的方式,这样利用while可以将i*i的值卡在当前值的范围内,不需要提前生成对应的数组。
class Solution:
def numSquares(self, n: int) -> int:
# 这是之前遇到的一道笔试题,需要重视起来了
# 首先需要找到所有的完全平方数
dp = [float('inf')] * (n+1)
dp[0] = 0
i = 1
# 先物品后背包
while i*i <= n:
for j in range(i*i,n+1):
dp[j] = min(dp[j-i*i]+1,dp[j])
i += 1
return dp[n]
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。