更弱智的算法学习day 38

322. 零钱兑换

dp[i]代表什么:

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

状态转移方程:

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

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

初始化:

由于要选最小,其他都初始化成inf,dp[0]初始化为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.完全平方数

dp[i]代表什么:

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

状态转移方程:

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

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

初始化:

由于要选最小,其他都初始化成inf,dp[0]初始化为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.单词拆分

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

dp[i]代表什么:

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

状态转移方程:

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

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

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

s[i-len(wordDict[j]) : i]==wordDict[j]

初始化:

由于是布尔数组,初始化都初始化False,但考虑dp[0]如果为False,无法正常推进,因为dp[s]全是False,所以dp[0]==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 分钟前
VID2WORLD: CRAFTING VIDEO DIFFUSION MODELSTO INTERACTIVE WORLD MODELS论文学习
学习
qq_423233904 分钟前
Python深度学习入门:TensorFlow 2.0/Keras实战
jvm·数据库·python
林深现海20 分钟前
【刘二大人】PyTorch深度学习实践笔记 —— 第四集:反向传播(凝练版)
pytorch·python·numpy
laplace012336 分钟前
Claude Code 逆向工程报告 笔记(学习记录)
数据库·人工智能·笔记·学习·agent·rag
lingggggaaaa40 分钟前
安全工具篇&Go魔改二开&Fscan扫描&FRP代理&特征消除&新增扩展&打乱HASH
学习·安全·web安全·网络安全·golang·哈希算法
菩提树下的凡夫42 分钟前
Python 环境管理工具
开发语言·python
索荣荣1 小时前
JavaToken实战指南:从原理到应用
开发语言·python
Albert Edison1 小时前
【Python】函数
java·linux·python·pip
2401_836563181 小时前
用Python读取和处理NASA公开API数据
jvm·数据库·python
AAD555888991 小时前
基于Faster RCNN的暴力行为检测模型优化与实现_1
python