欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > 2025-2-27-4.10 动态规划(0-1 背包问题)

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

2025/2/28 18:49:16 来源:https://blog.csdn.net/weixin_42269028/article/details/145893874  浏览:    关键词:2025-2-27-4.10 动态规划(0-1 背包问题)

文章目录

  • 4.10 动态规划(0-1 背包问题)
    • 494. 目标和
      • 方法一:递归
      • 方法二:递推
      • 方法三:递推+滚动数组
      • 方法四:递推+单个数组

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

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

方法一:递归

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 0m = s // 2@cache #缓存装饰器,避免重复计算 dfs 的结果def dfs(i: int, c: int) -> int:if i < 0:return 1 if c == 0 else 0if 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)

方法二:递推

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 0m = s // 2n = len(nums)f = [[0] * (m + 1) for _ in range(n+1)]f[0][0] = 1for 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]

方法三:递推+滚动数组

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 0m = s // 2n = len(nums)f = [[0] * (m + 1) for _ in range(2)]f[0][0] = 1for 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]

方法四:递推+单个数组

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 0m = s // 2n = len(nums)f = [1] + [0] * mfor x in nums:for c in range(m,x-1,-1):f[c] += f[c - x]return f[m]

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词