
# 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]



















