01背包 完全背包

01背包 完全背包

出自灵神的算法精讲

回溯三问

  • 当前操作:枚举i个物品选或者不选:不选,剩余容量不变;选:剩余容量减少v[i]
  • 子问题:在剩余容量为c时,从i个物品中得到的最大价值和
  • 下一个子问题 :分类讨论
    • 不选,在剩余容量为c时, 从前i - 1个物品中得到的最大价值和
    • 选,在剩余容量为c - w[i]时,从前i - 1个物品中得到的最大价值和
      dsf(i, c) = max(dfs(i - 1, c), dfs(i - 1, c - v[i]) + w[i]

代码

# 01背包
def dfs(i, c):
    if i < 0: 
        return 0
    if c < v[i]:
        return dfs(i - 1, j)
    return max(dfs(i - 1, c), dfs(i - 1 c - v[i]) + w[i])
return dfs(n - 1, capacity) 

对应例题:目标和
ac_coder

class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        n = len(nums)
        target += sum(nums)
        if target < 0 or target % 2:
            return 0
        target //= 2

        @cache
        def dfs(i, c):
            if i < 0:
                return 1 if c == 0 else 0
            if c < nums[i]:
                dfs(i - 1, c)
            return dfs(i - 1, c) +  dfs(i - 1, c - nums[i])
        return dfs(n - 1, target)
        
class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        for (auto c: nums) target += c;
        if (target % 2 || target < 0) return 0;
        target /= 2;

        int n = nums.size(), cache[n][target + 1];
        memset(cache, -1, sizeof cache);
        function<int(int, int)> dfs = [&](int i, int c) -> int {
            if (i < 0) return c == 0;
            int &res = cache[i][c];
            if (res != -1) return res;
            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);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值