您现在的位置是:首页 >技术杂谈 >day44|动态规划7-装满背包最小用多少件物品(零钱兑换,完全平方数)网站首页技术杂谈

day44|动态规划7-装满背包最小用多少件物品(零钱兑换,完全平方数)

dearbobby 2024-07-22 06:01:02
简介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. 零钱兑换(装满背包最小用多少件物品)

  1. 如果求组合数就是外层for循环遍历物品,内层for遍历背包。
  2. 如果求排列数就是外层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]

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。