更弱智的算法学习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)
相关推荐
用户29869853014几秒前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
决战灬5 分钟前
langgraph之interrupt(事例篇)
人工智能·python·agent
IPdodo_14 分钟前
Codex 总是 Reconnecting?从 401 到响应流中断的排查方法
python·requests
京和动物医院·总院23 分钟前
2026年未央区宠物医院:如何挑选最适合您爱宠的健康守护者
大数据·人工智能·python
刘小八26 分钟前
RAG 文档切分不是越细越好:选择 Chunk Size 与 Overlap
人工智能·python·语言模型
互联网中的一颗神经元28 分钟前
小白python入门 - 23. Python 正则表达式的应用
python·正则表达式
雪碧透心凉_29 分钟前
while 循环与循环嵌套
开发语言·python
minglie132 分钟前
zynq高频小数据量PS闭环的三个实验-第0课:目的和目标
学习
初学者,亦行者35 分钟前
利用pyecharts自动化绘制漏斗图保姆级教程
python·信息可视化·数据分析
这就是佬们吗44 分钟前
Python入门⑤-异常处理、文件操作与实战项目
开发语言·数据库·python·算法·pycharm