2025-2-27-4.10 动态规划(0-1 背包问题)

文章目录

4.10 动态规划(0-1 背包问题)

0-1 背包问题,现在有点明了了,以前只觉得高大上,现在看来就是一个固定的模型思路,体积有限,物品有限,获取在固定体积下能得到的最大的物品价值。

原视频讲解链接

494. 目标和

题目链接

给你一个非负整数数组 nums 和一个整数 target 。

向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :

例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。

返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

示例 1:

输入:nums = [1,1,1,1,1], target = 3

输出:5

解释:一共有 5 种方法让最终目标和为 3 。

-1 + 1 + 1 + 1 + 1 = 3

+1 - 1 + 1 + 1 + 1 = 3

+1 + 1 - 1 + 1 + 1 = 3

+1 + 1 + 1 - 1 + 1 = 3

+1 + 1 + 1 + 1 - 1 = 3

示例 2:

输入:nums = [1], target = 1

输出:1

提示:

  • 1 <= nums.length <= 20
  • 0 <= nums[i] <= 1000
  • 0 <= sum(nums[i]) <= 1000
  • -1000 <= target <= 1000

题目解析:有一定的数学推导,具体看灵神的题解,不难理解。

方法一:递归

python 复制代码
class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:

        """
        方法一:递归
        时间复杂度:O(nm),其中 n 为 nums 的长度,m 为 nums 的元素和减去 target 的绝对值。
            由于每个状态只会计算一次,动态规划的时间复杂度 = 状态个数 × 单个状态的计算时间。
            本题状态个数等于 O(nm),单个状态的计算时间为 O(1),所以动态规划的时间复杂度为 O(nm)。
        空间复杂度:O(nm)。保存多少状态,就需要多少空间。
        """

        s = sum(nums) - abs(target)
        if s < 0 or s % 2:
            return 0
        m = s // 2

        @cache #缓存装饰器,避免重复计算 dfs 的结果
        def dfs(i: int, c: int) -> int:
            if i < 0:
                return 1 if c == 0 else 0
            if c < nums[i]:
                return dfs(i - 1, c)
            return dfs(i - 1, c) + dfs(i - 1, c - nums[i]) # 不选 + 选
        
        return dfs(len(nums) - 1, m)
        

方法二:递推

python 复制代码
class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:

        """
        方法二:递推
        时间复杂度:O(nm),
            其中 n 为 nums 的长度,
            m 为 nums 的元素和减去 target 的绝对值。
        空间复杂度:O(nm)。保存多少状态,就需要多少空间。
        """

        s = sum(nums) - abs(target)
        if s < 0 or s % 2:
            return 0
        m = s // 2
        n = len(nums)

        f = [[0] * (m + 1) for _ in range(n+1)]
        f[0][0] = 1

        for i, x in enumerate(nums):
            for c in range(m+1):
                if c < x:
                    f[i + 1][c] = f[i][c]
                else:
                    f[i + 1][c] = f[i][c] + f[i][c - x]
        return f[n][m]
        

方法三:递推+滚动数组

python 复制代码
class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:


       
        """
        方法三:递推+滚动数组
        时间复杂度:O(nm),
            其中 n 为 nums 的长度,
            m 为 nums 的元素和减去 target 的绝对值。
        空间复杂度:O(m)。保存多少状态,就需要多少空间。
        """

        s = sum(nums) - abs(target)
        if s < 0 or s % 2:
            return 0
        m = s // 2
        n = len(nums)

        f = [[0] * (m + 1) for _ in range(2)]
        f[0][0] = 1

        for i, x in enumerate(nums):
            for c in range(m+1):
                if c < x:
                    f[(i + 1)%2][c] = f[i%2][c]
                else:
                    f[(i + 1)%2][c] = f[i%2][c] + f[i%2][c - x]
        return f[n%2][m]
 

方法四:递推+单个数组

python 复制代码
class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:

        """
        方法四:递推+简化数组
        时间复杂度:O(nm),
            其中 n 为 nums 的长度,
            m 为 nums 的元素和减去 target 的绝对值。
        空间复杂度:O(m)。保存多少状态,就需要多少空间。
        """

        s = sum(nums) - abs(target)
        if s < 0 or s % 2:
            return 0
        m = s // 2
        n = len(nums)

        f = [1] + [0] * m

        for x in nums:
            for c in range(m,x-1,-1):
                    f[c] += f[c - x]
        return f[m]
相关推荐
t198751287 小时前
TOA定位算法MATLAB实现(二维三维场景)
开发语言·算法·matlab
喵手7 小时前
Python爬虫实战:用代码守护地球,追踪WWF濒危物种保护动态!
爬虫·python·爬虫实战·濒危物种·零基础python爬虫教学·wwf·濒危物种保护动态追踪
梦想的旅途27 小时前
如何通过 QiWe API 实现企业微信主动发消息
开发语言·python
jllllyuz7 小时前
粒子群算法解决资源分配问题的MATLAB实现
开发语言·算法·matlab
喵手7 小时前
Python爬虫实战:自动化抓取 Pinterest 热门趋势与创意!
爬虫·python·爬虫实战·pinterest·零基础python爬虫教学·采集pinterest热门趋势·热门趋势预测
renhongxia17 小时前
从模仿到创造:具身智能的技能演化路径
人工智能·深度学习·神经网络·算法·机器学习·知识图谱
凌晨一点的秃头猪7 小时前
Python文件操作
开发语言·python
小张贼嚣张7 小时前
数据分析全流程实战:Python(Pandas/Matplotlib/Numpy)+ MySQL(附可下载数据源+多图形绘制)
python·数据分析·pandas
努力的小白o(^▽^)o7 小时前
面向课堂考勤场景的桌面端人脸识别签到系统
python·人脸识别
Sarvartha7 小时前
递归、回溯与动态规划学习笔记
笔记·学习·动态规划