DP:完全背包

10 分钟

完全背包和 01 背包只差一个字:每件物品可以拿无限次。状态定义一样,一维写法的代码也几乎一样,唯一的区别是——容量 改成从小到大正序枚举。

for (int i = 0; i < n; i++)
    for (int j = w[i]; j <= W; j++)      // 正序!
        dp[j] = max(dp[j], dp[j - w[i]] + v[i]);

为什么正序就对了?正序时 已经在本轮被更新过,可能已经拿了一个第 件,再用它更新 ,就相当于允许第 件被拿第二次、第三次……正好对应"无限次"。这和 01 背包倒序保证"只拿一次"正好相反,方向就是二者的全部差别。

凑硬币问题(每种硬币无限枚)用的就是完全背包:把硬币面额当重量,正序枚举。复杂度 。坑:记牢"01 倒序、完全正序",写反了答案就错,这也是考试最爱设的陷阱。

小纸条

凑硬币用哪种背包?

登录 后可看答案

DP:完全背包 · 考级冲刺 · op599 课程