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 倒序、完全正序",写反了答案就错,这也是考试最爱设的陷阱。
小纸条
凑硬币用哪种背包?
登录 后可看答案