更弱智的算法学习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)
相关推荐
花酒锄作田7 小时前
Pydantic校验配置文件
python
hboot8 小时前
AI工程师第四课 - 深度学习入门
pytorch·python·神经网络
ZhengEnCi18 小时前
P2M-Matplotlib折线图完全指南-从数据可视化到趋势分析的Python绘图利器
python·matlab·数据可视化
ZhengEnCi20 小时前
P2L-Matplotlib饼图完全指南-从数据可视化到图表定制的Python绘图利器
python·matlab
曲幽20 小时前
你的REST接口还在“过度投喂”数据吗?——FastAPI + GraphQL实战避坑指南
python·fastapi·web·graphql·route·cors·rest·strawberry
用户83580861879121 小时前
基于 Self-RAG 与列表级重排序的进阶 RAG 系统设计与实现
python
Warson_L2 天前
Python `Annotated` 与 LangGraph Reducer 学习笔记
python
韩师傅2 天前
海天线算法的前世今生
python·计算机视觉
韩师傅2 天前
当你的甲方设备过烂,要如何快速出效果?
python·计算机视觉
Warson_L2 天前
LangGraph的MessageState and HumanMessage
python