# capacity:背包容量
# w[i]: 第 i 个物品的体积
# v[i]: 第 i 个物品的价值
# 返回:所选物品体积和不超过 capacity 的前提下,所能得到的最大价值和
def zero_one_knapsack(capacity:int,w:List[int],v:List[int]) -> int:
n = len(w)
@cache #记忆化搜索
def dfs(i,c):
if i < 0:
return 0
if c < w[i]:
return dfs(i-1,c)
return max(dfs(i-1,c),dfs(i-1,c-w[i])+v[i])
return dfs(n-1,capacity)
494. 目标和 - 力扣(LeetCode)
给你一个非负整数数组 nums
和一个整数 target
。向数组中的每个整数前添加 '+'
或 '-'
,然后串联起所有整数,可以构造一个 表达式 :
- 例如,
nums = [2, 1]
,可以在2
之前添加'+'
,在1
之前添加'-'
,然后串联起来得到表达式"+2-1"
。
返回可以通过上述方法构造的、运算结果等于 target
的不同 表达式 的数目。
>>思考和分析:
- 正数和:p
- 负数和:s-p
- p-(s-p) = t
- 2p=s+t
- 化简可得: p=(s+t)/2
(1)记忆化搜索
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
target += sum(nums)
if target < 0 or target%2: # 负数 or 奇数
return 0 # 方案数为0
target //= 2
n = len(nums)
# 记忆化搜索
@cache
def dfs(i,c):
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(n-1,target)
(2)1:1 翻译成递推
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
target += sum(nums)
if target < 0 or target%2: # 负数 or 奇数
return 0 # 方案数为0
target //= 2
n = len(nums)
# 二维dp
f = [[0]*(target+1)for _ in range(n+1)]
f[0][0] = 1
for i,x in enumerate(nums):
for c in range(target+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][target]
- 优化空间
方式一:二维数组优化
- f[(i+1)%2][c] = f[i%2][c] + f[i%2][c-w[i]]
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
# 二维dp
f = [[0]*(target+1)for _ in range(2)]
f[0][0] = 1
for i,x in enumerate(nums):
for c in range(target+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][target]
方式二:一维数组优化
- f[i+1][c] = f[i][c] + f[i][c-w[i]]
- f[c]=f[c]+f[c-w[i]]
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
target += sum(nums)
if target < 0 or target%2: # 负数 or 奇数
return 0 # 方案数为0
target //= 2
n = len(nums)
# 一维dp
f = [0]*(target+1)
f[0] = 1
for x in nums:
for c in range(target,x-1,-1):
f[c] = f[c] + f[c-x]
return f[target]