代码随想录27期|Python|Day44|​动态规划|完全背包 |​ 322. 零钱兑换| 279.完全平方数 |139.单词拆分

322. 零钱兑换

本题是求最小的组合情况,所以递推公式取较小值:dp[j] = min(dp[j], dp[j-coin]+1);

1、确定dp含义

dp在这里表示背包容量能填满的时候所需要硬币数量的最小值。

2、确定递推公式

dp[j] = min(dp[j], dp[j-coin]+1)。

3、确定初始化

dp[0]表示在目标值为0的时候组合数的个数,其余的dp值取为inf,因为需要取最小值。

4、确定遍历顺序

由于是取最小的方法数,所以排列或者组合其实都无所谓。

class Solution(object):
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        dp = [float('inf')] * (amount+1)  # 初始化为最大值,因为后面是求最小值的递推
        dp[0] = 0  # 目标为0的时候没有可行方法(因为没有0的coin)
        for coin in coins:
            for j in range(coin, amount+1):  # 正序遍历 or 后续遍历都可以(因为只看最小的元素数)
                dp[j] = min(dp[j], dp[j-coin]+1)
        return -1 if dp[-1] == float('inf') else dp[-1]  # 注意比较后输出

279. 完全平方数

本题是上面一道题的扩展。所不同的是需要进行一步求解满足条件的最大平方数的基底。

class Solution(object):
    def numSquares(self, n):
        """
        :type n: int
        :rtype: int
        """
        dp = [float('inf')] * (n+1)
        dp[0] = 0
        Num = int(sqrt(n)) + 1  # 先计算出符合条件的最大完全平方数的基底
        for num in range(1, Num+1):  # 从1开始
            for j in range(num ** 2, n+1):
                dp[j] = min(dp[j], dp[j-num ** 2]+1)
        return dp[-1]

139. 单词拆分

本题是字符串尺度上的背包问题。

1、确定dp数组含义

dp[j]表示在给定字符串j位置是否可以由字典中的元素构成。是一个bool类型。

2、确定确定递推公式

在两个条件都满足的情况下才可以判断当前为true:

(1)在加入长度为j-i的字符串前dp[j]已经是true;

(2)目标字符串s[i-j]这个子串是在字典里的。

3、确定初始化

由于递推公式是吧满足条件的设置为true,所以初始化为false。又因为需要dp[0]来进行and操作的递推,所以dp[0]=true(本身没有含义,仅占位)。

4、确定遍历顺序

和组合数凑够目标和不一样,本题字符串需要保证顺序也一致,所以需要确定为组合数:先便利背包,再遍历物品(保证每个背包容量都能遍历一遍物品,才能达到排列的效果)。

class Solution(object):
    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: List[str]
        :rtype: bool
        """
        dp = [False] * (len(s)+1)
        dp[0] = True
        for i in range(1, len(s)+1):
            for j in range(i):
                if dp[j] == True and s[j:i] in wordDict:
                    dp[i] = True
        return dp[-1]

Day44完结!!!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值