494. 目标和 - 01背包中"装满背包有几种方法"的问题

✅01背包中"装满背包有几种方法"的问题

这道题难就难在如何把题面转化为背包问题

💡由题知left + right = sum, left - right = target,故有left = (sum + target) / 2,则此时就转化为了装满容量为left的背包有几种方法

当然这里要讨论一些非法情况

  • 如果sum + target < 0,则非法
  • 如果(sum + target)不是偶数,则非法(因为这样子凑不了left

dp数组的含义

  • dp[j]是装满容量为j的背包的方法数

递推公式

  • 容量为j的背包可以怎么得来呢,可以是容量为j - nums[0]的背包加了一个物品nums[0]而得来,可以是容量为j - nums[1]的背包加了一个物品nums[1]而得来。故这里装满容量为j的背包的方法数就是把[0, nums.size() - 1]里面能够装下的物品(``j >= nums[i]`)的方法数都加起来

  • 故由上,对于装满背包的方法数的通用公式(大概):dp[j] += dp[j - nums[i]],因为是要算方法数,所以是+=

初始化

  • 这里因为要递增上去,所以要得到答案,需使得dp[0] = 1,其实这个也很好理解,当背包容量为0时,装满它的方法只有一个:什么也不装!

遍历顺序

  • 物品正序,背包容量倒序(因为01背包每个物品只放一次),老生常谈
class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        int sum = 0;
        //算总和
        for (int i = 0; i < nums.size(); i++) {
            sum += nums[i];
        }
        //判断非法条件
        if ((sum + target) % 2 != 0 || (sum + target) / 2 < 0)return 0;
        target = (sum + target) / 2;
        vector<int>dp (1020, 0);
        dp[0] = 1;
        //经典01背包
        for (int i = 0; i < nums.size(); i++) {
            for (int j = target; j >= nums[i]; j--) {
                dp[j] += dp[j - nums[i]];
            }
        }
        return dp[target];
    }
};
posted @   北原春希  阅读(177)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示