Day 45 | 动态规划 07

96 阅读1分钟

70. 爬楼梯

完全背包的概念 每一步可以走多次

    def climbStairs(self, n: int) -> int:
        # 完全背包
        # 相当于求组合数
        dp = [0] * (n+1)
        dp[0] = 1
        dp[1] = 1
        # 相当于设置步长
        m = 2
        for i in range(2,n+1):
            for j in range(1,m+1):
                dp[i] += dp[i-j]
        return dp[-1]

322. 零钱兑换

dp元素表示为 组成当前下标amount所需的个数

def coinChange(self, coins: List[int], amount: int) -> int:

    # 背包问题

    # 因为要用min
    dp = [10001] * (amount+1)

    dp[0] = 0
    
    for i in range(len(coins)):
        if coins[i] <= amount:
            dp[coins[i]] = 1

    for i in range(amount+1):
        for j in range(len(coins)):
            if coins[j] <= i:
                # 组成coins的方法 dp[i-coins[j]]+1 说明加上coins[j]组成i的硬币数量
                dp[i] = min(dp[i], dp[i-coins[j]] + 1)
    
    # print(dp)

    return dp[-1] if dp[-1] != 10001 else -1

如果求组合数就是外层for循环遍历物品,内层for遍历背包。 因为组合数是无序的。

如果求排列数就是外层for遍历背包,内层for循环遍历物品。

279. 完全平方数

因为条件为平方数的个数,为了保证是平方数,内层循环(即物品)直接用平方数的形式放入

def numSquares(self, n: int) -> int:
    dp = [n+1] * (n+1)
    dp[0] = 0
    dp[1] = 1
    for i in range(n+1):
        for j in range(1, int(sqrt(i))+1):
            dp[i] = min(dp[i], dp[i-j*j] + 1)
    print(dp)
    return dp[-1]