377.组合总和 Ⅳ(背包)

链接:377. 组合总和 Ⅳ - 力扣(LeetCode)

题解:

组合总和 IV

dpi 目标位i的组合组数是多少

dpi = dpi-A0 + dpi-A\[1] .. dp1-A\[n-1],枚举所有最后一个数字的可能

cpp 复制代码
class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        int len = nums.size();
        if (len <= 0) {
            return 0;
        }
        vector<unsigned long long> dp(target + 1, 0);
        dp[0] = 1;
        for (int i = 0; i <= target; ++i) {
            for (int j = 0; j < nums.size(); ++ij) {
                if (i - nums[j] >= 0) {
                    dp[i] += dp[i - nums[j]];
                }
            }
        }
        return dp[target];
    }
};

外层循环决定"转移时被复用的 dp 值是完整的,还是只含部分物品的"。

本题 dp[j] 的语义是"和为 j 的排列数",转移是:

cpp

复制代码
dp[j] = Σ_{num ∈ nums, num ≤ j} dp[j - num]

要让这个式子成立,右边每个 dp[j - num] 必须是完整的排列数(所有物品都能参与)。而它什么时候完整,取决于循环顺序。

1. 从"最后一步"看

一个和为 j 的排列,最后一步 可以是任意 num,前面部分是任意和为 j - num 的排列。

所以:

text

复制代码
dp[j] = dp[j-1] + dp[j-2] + dp[j-3] + ...
        ↑ 最后一步是 1、2、3……

这里 dp[j-num] 必须是"任何物品都能用"的完整排列。

外层容量 j:

cpp

复制代码
for (int j = 1; j <= target; ++j)
    for (int num : nums)
        dp[j] += dp[j - num];

当你在第 j 层累加时,dp[j-num] 已经在之前的轮次里把所有物品都累加完了,它是完整的。✓

外层物品 num:

cpp

复制代码
for (int num : nums)
    for (int j = num; j <= target; ++j)
        dp[j] += dp[j - num];

当你在处理物品 num 时,dp[j-num] 只吸收了当前及之前处理过的物品,还没轮到后面的物品。它是"半成品"。用半成品去转移,就等于强制"前面的物品编号 ≤ 当前物品编号"

相关推荐
肖永威1 小时前
AI大模型不是答案机:研发场景下的多模型迭代工作流
人工智能·1024程序员节
海盗12341 小时前
微软技术日报 2026-10-24:CA 私钥是 4,Windows 封了中间证书未动父根
人工智能·机器人·aigc·1024程序员节
奶酪博士1 小时前
【1024快乐】用HTML写一个本地版心愿墙页面
html·1024程序员节
wshzd1 小时前
LLM之Agent(117)|DeepSeek-Harness(二十四)Host/Client 分离与 Typert RPC 生成
1024程序员节
长不大的杨瑞杰1 小时前
OpenCode v2 CI 与自动化实战:无交互运行、权限收口与制品闭环
运维·人工智能·ci/cd·自动化·软件工程·1024程序员节
limit00751 小时前
三维场景五段链路的资源与依赖排查
1024程序员节
骑着蜗牛撵大象3271 小时前
N1 小盒子撑起 AI 接口中转层:New-API 接管本地 Ollama,用 Token 分发模型能力
docker·llama·1024程序员节·api网关·飞牛nas·new-api
java1234_小锋1 小时前
【技术专题】CSS3 网页技术 - CSS3 简介 & CSS 语法:选择器、属性、值、声明块
css3·1024程序员节
前端 贾公子1 小时前
LangGraph == 顺序结构
1024程序员节