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]
相关推荐
COOCC16 分钟前
激活函数全解析:定义、分类与 17 种常用函数详解
人工智能·深度学习·神经网络·算法·机器学习·计算机视觉·自然语言处理
林下清风~15 分钟前
力扣hot100——347.前K个高频元素(cpp手撕堆)
算法·leetcode·职场和发展
沃洛德.辛肯32 分钟前
PyTorch 的 F.scaled_dot_product_attention 返回Nan
人工智能·pytorch·python
noravinsc44 分钟前
人大金仓数据库 与django结合
数据库·python·django
豌豆花下猫1 小时前
Python 潮流周刊#102:微软裁员 Faster CPython 团队(摘要)
后端·python·ai
进击的小白菜1 小时前
Java回溯算法解决非递减子序列问题(LeetCode 491)的深度解析
java·算法·leetcode
yzx9910131 小时前
Gensim 是一个专为 Python 设计的开源库
开发语言·python·开源
麻雀无能为力2 小时前
python自学笔记2 数据类型
开发语言·笔记·python
Ndmzi2 小时前
matlab与python问题解析
python·matlab
懒大王爱吃狼2 小时前
怎么使用python进行PostgreSQL 数据库连接?
数据库·python·postgresql