当前位置: 首页 > article >正文

leetcode刷题-动态规划06

代码随想录动态规划part06|322. 零钱兑换、279.完全平方数、139.单词拆分

    • 322. 零钱兑换
    • 279.完全平方数
    • 139.单词拆分
    • 关于多重背包,你该了解这些!
    • 背包问题总结篇!

322. 零钱兑换

leetcode题目链接
代码随想录文档讲解

思路

完全背包整理:

  1. 完全背包理论基础:装满这个背包可得的最大价值(遍历顺序可以颠倒)
  2. 零钱兑换2:装满背包有多少种方法(每种方法不强调顺序,组合数)(先遍历物品再遍历背包)
  3. 组合总和4:装满背包有多少种方法(每种方法强调顺序,排列数)(先遍历背包再遍历物品)
    本题求,装满背包最少用多少件物品

动态规划五部曲

  1. dp[j]数组的含义:装满容量为j的背包的最少物品数量为dp[j],最终求dp[amount]
  2. 递推公式:dp[j] = min(dp[j], dp[j-coins[i]]+1)
    dp[j-coins[i]]+1代表放物品i,数量+1
  3. 初始化,dp[0]=0,非零下标初始化为INT_MAX
  4. 遍历顺序,考不考虑顺序都可以,不会影响最小值,所以怎么遍历都可以

python代码

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        dp = [float('inf')]*(amount+1)
        dp[0] = 0
        for i in range(len(coins)):
            for j in range(coins[i], amount+1): //避免下标出现负数
                dp[j] = min(dp[j], dp[j-coins[i]]+1)
        return dp[amount] if dp[amount]!= float('inf') else -1

279.完全平方数

leetcode题目链接
代码随想录文档讲解

思路

与上题类似

动态规划五部曲

  1. dp[j]数组的含义:和为j的完全平方数的最少数量为dp[j],最终求dp[n]
  2. 递推公式:dp[j] = min(dp[j], dp[j-coins[i]]+1)
  3. 初始化,dp[0]=0,dp[1]=1,非零下标初始化为INT_MAX
  4. 遍历顺序,考不考虑顺序都可以,不会影响最小值,所以怎么遍历都可以

python代码

class Solution:
    def numSquares(self, n: int) -> int:
        dp = [float('inf')]*(n+1)
        dp[0] = 0
        dp[1] = 1 // 第一次没加这行,出现报错,测试样例为1
        nums = []
        for i in range(n):
            nums.append(i*i)
        for i in range(len(nums)):
            for j in range(nums[i], n+1):
                dp[j] = min(dp[j], dp[j-nums[i]]+1)
        return dp[n]
# 代码随想录答案
class Solution:
    def numSquares(self, n: int) -> int:
        dp = [float('inf')] * (n + 1)
        dp[0] = 0

        for i in range(1, int(n ** 0.5) + 1):  # 遍历物品
            for j in range(i * i, n + 1):  # 遍历背包
                # 更新凑成数字 j 所需的最少完全平方数数量
                dp[j] = min(dp[j - i * i] + 1, dp[j])
        return dp[n]
 
class Solution:
    def numSquares(self, n: int) -> int:
        dp = [float('inf')] * (n + 1)
        dp[0] = 0

        for i in range(1, n + 1):  # 遍历背包
            for j in range(1, int(i ** 0.5) + 1):  # 遍历物品
                # 更新凑成数字 i 所需的最少完全平方数数量
                dp[i] = min(dp[i], dp[i - j * j] + 1)
        return dp[n]

139.单词拆分

leetcode题目链接
代码随想录文档讲解

思路
可以用回溯算法暴力搜索
动态规划方法:
字符串s为背包,字符串列表为物品

  1. dp[i]=true,长度为i的字符串s能被字符串列表组成,最终结果为dp[s.size]
  2. 递推公式:if [j,i] & dp[j]==true: dp[i]=true
  3. 初始化:dp[0] = true,下标非0的dp[i]初始化为false
  4. 遍历顺序:这里字符串s对于列表中的元素组成是有顺序的,就是排列数,先遍历背包再遍历物品

python代码

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> 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[len(s)]
# 代码随想录,写法二
class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        dp = [False]*(len(s) + 1)
        dp[0] = True
        # 遍历背包
        for j in range(1, len(s) + 1):
            # 遍历单词
            for word in wordDict:
                if j >= len(word):
                    dp[j] = dp[j] or (dp[j - len(word)] and word == s[j - len(word):j])
        return dp[len(s)]

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

多重背包代码随想录

背包问题总结篇!

总结篇代码随想录


http://www.kler.cn/a/552941.html

相关文章:

  • 23种设计模式 - 空对象模式
  • 使用 ollama 在 windows 系统本地部署 deepseek r1 模型
  • 深入解析 Flutter GetX
  • Redis 客户端C++使用
  • GoFound 与 MySQL 集成优化方案
  • 寒假总结与心得
  • 侯捷 C++ 课程学习笔记:设计模式在面向对象开发中的应用
  • Python 爬虫入门:从基础到实战
  • 修改项目的一些前端记录(自用)
  • MySQL-慢SQL解析及调试分析思路
  • 可变列二维数组【C语言】
  • 内网常见问题处理
  • java数据结构_优先级队列(堆)_6.1
  • 开源元搜索引擎SearXNG:使用Docker详细搭建部署与使用
  • 【OS安装与使用】part4-ubuntu22.04安装anaconda
  • 【R语言】绘图
  • ONNX Runtime 与 CUDA、cuDNN 的版本对应
  • “三次握手”与“四次挥手”:TCP传输控制协议连接过程
  • 在Kubernetes上部署DeepSeek-R1进行高效AI推理
  • C#```