更弱智的算法学习day 38

322. 零钱兑换

dpi代表什么:

对于给定整数i,能凑成总金额所需的最少硬币的个数为dpi

状态转移方程:

dpi = min(dpi-j + 1 , dpi )

也即选和不选两种情况,不选就是dpi,选了就是dpi-j+1(多加一枚i硬币)

初始化:

由于要选最小,其他都初始化成inf,dp0初始化为0,想凑成amount只有0种方法

遍历顺序:

由于是组合,且是完全背包

组合先便利物品再遍历背包;排列先便利背包再遍历物品

01背包遍历背包时需要倒序;完全背包正序

故先正向遍历硬币,再正向遍历amount

python 复制代码
class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        dp = [inf] * (amount + 1)

        dp[0] = 0
        for j in coins:
            for i in range(j, amount+1):
                    dp[i] = min(dp[i-j] + 1 , dp[i] )

        if dp[amount] == inf:
            return -1
        
        return dp[amount]

279.完全平方数

dpi代表什么:

对于给定整数i,能凑成和为n的所需的完全平方数的最小个数为dpi

状态转移方程:

dpi = min(dpi-j + 1 , dpi )

也即选和不选两种情况,不选就是dpi,选了就是dpi-j+1(多加一个i*i完全平方数)

初始化:

由于要选最小,其他都初始化成inf,dp0初始化为0,想凑成n只有0种方法

遍历顺序:

由于是组合,且是完全背包

组合先便利物品再遍历背包;排列先便利背包再遍历物品

01背包遍历背包时需要倒序;完全背包正序

故先正向遍历完全平方数,再正向遍历n

其中:

  • 1 <= n <= 10**4
  • 故i范围在0-100即可
python 复制代码
class Solution:
    def numSquares(self, n: int) -> int:
        dp = [inf] * (n+1)

        dp[0] = 0

        for i in range(101):
            for j in range(i*i, n+1):
                dp[j] = min(dp[j], dp[j-i*i]+1)

        return dp[n] 

139.单词拆分

该题略微复杂,需要进行匹配验证,仔细理解一下

dpi代表什么:

对于给定字符串s,考虑其前i位长度的字符能否被worddict列表中的字符串加和表示的布尔数组

状态转移方程:

我的理解是,对于没有加入字符串worddict【j】的dp【i-len【j】】而言:

首先要满足dp【i-len【j】】能被worddict列表中的字符串加和表示,也即==True

其次要满足加上字符串j之后,和dp【i】相同,也即:实际上是把worddict【j】长度的s字符串的内容切下来和真正的worddict【j】比较

si-len(wordDict\[j) : i]==wordDictj

初始化:

由于是布尔数组,初始化都初始化False,但考虑dp0如果为False,无法正常推进,因为dps全是False,所以dp0==True

遍历顺序:

由于是排列,且是完全背包

组合先便利物品再遍历背包;排列先便利背包再遍历物品

01背包遍历背包时需要倒序;完全背包正序

故先正向遍历s的长度,再正向遍历worddict

python 复制代码
class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        dp = [False] * (len(s) + 1)

        dp[0] = True

        for i in range(len(s)+1):
            for j in range(len(wordDict)):
                if len(wordDict[j]) <= i:
                    if dp[i-len(wordDict[j])] == True and s[i-len(wordDict[j]) : i]==wordDict[j]  :
                        dp[i] = True
                        break

                    
        return dp[len(s)]

关于多重背包,你该了解这些!

区别主要体现在下面这里,还需要遍历背包种某物品的可能选择数量k

python 复制代码
# 01背包的状态转移(单一选择)
dp[j] = max(dp[j], dp[j - weight] + value)

# 多重背包的状态转移(多重选择)
for k in range(1, nums[i] + 1):  # 需要遍历所有可能的选择数量
    if k * weight <= j:
        dp[j] = max(dp[j], dp[j - k*weight] + k*value)
相关推荐
一隅论数智1 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
默_笙1 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
XiHongShi20161 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
qq_426003961 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫1 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
长沙三为智能科技1 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
爱吃苹果的日记本1 天前
离散数学第六课
学习·离散数学
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
只睡四小时1 天前
Canvas 弹道联机实战:700 行 + 固定时间步长
python·websocket·html5·游戏开发·canvas