软件设计师 · 高频练习

0/1背包压缩成一维数组后,容量为什么必须从大到小更新?

中级 单选题 第 1084 题 较难 软件设计师0/1背包动态规划状态压缩倒序枚举
题目

0/1背包中,每件物品最多选择一次。将二维状态压缩为一维dp数组后,处理重量为w、价值为v的当前物品时,常写成for(c=C;c>=w;c--)。容量从大到小更新的主要原因是()。

A 避免本轮刚更新的dp[c-w]再次被使用,从而把同一件物品重复选择
B 保证所有物品都必须被选择
C 把0/1背包自动改成完全背包
D 使时间复杂度从O(nC)降为O(log C)
题目类型:原创高频练习题 用途:用于帮助理解软件设计师相关考点和答案解析,不等同于官方真题。
正确答案
A
答案解析

一维压缩后,新旧两层状态共用同一数组。倒序时dp[c-w]还保留处理当前物品之前的值;若正序,较小容量刚写入的新值可能马上被较大容量使用,相当于同一物品选了多次。

选项分析

A

正确。倒序保证转移来源属于处理当前物品前的状态。

B

错误。0/1背包允许物品不选,目标通常是容量约束下价值最大。

C

错误。正序才会形成当前物品可重复使用的完全背包效果。

D

错误。空间从O(nC)降到O(C),时间复杂度仍通常为O(nC)。

本题为什么容易错

很多同学只背“01倒、完全正”,一换成具体数组就乱。最可靠的方法是问dp[c-w]应该来自上一件物品处理完的旧层,还是允许来自当前层。

先看结论

简短答案

0/1背包压缩成一维数组后,容量为什么必须从大到小更新,正确答案是 A(避免本轮刚更新的dp[c-w]再次被使用,从而把同一件物品重复选择)。一维压缩后,新旧两层状态共用同一数组。倒序时dp[c-w]还保留处理当前物品之前的值;若正序,较小容量刚写入的新值可能马上被较大容量使用,相当于同一物品选了多次。

解析

易混淆概念对比表

概念本题判断区别要点记忆提示
避免本轮刚更新的dp[c-w]再次被使用,从而把同一件物品重复选择 本题正确答案 正确。倒序保证转移来源属于处理当前物品前的状态。 看到题干核心场景时优先联想到它
保证所有物品都必须被选择 本题干扰项 错误。0/1背包允许物品不选,目标通常是容量约束下价值最大。 看到该词不要急着选,先判断是否真正解决题干问题
把0/1背包自动改成完全背包 本题干扰项 错误。正序才会形成当前物品可重复使用的完全背包效果。 看到该词不要急着选,先判断是否真正解决题干问题
使时间复杂度从O(nC)降为O(log C) 本题干扰项 错误。空间从O(nC)降到O(C),时间复杂度仍通常为O(nC)。 看到该词不要急着选,先判断是否真正解决题干问题
本题易混淆选项怎么区分
  • 保证所有物品都必须被选择:错误。0/1背包允许物品不选,目标通常是容量约束下价值最大。
  • 把0/1背包自动改成完全背包:错误。正序才会形成当前物品可重复使用的完全背包效果。
  • 使时间复杂度从O(nC)降为O(log C):错误。空间从O(nC)降到O(C),时间复杂度仍通常为O(nC)。
复习

知识点详解

二维转移为dp[i][c]=max(dp[i-1][c],dp[i-1][c-w]+v)。压缩后必须确保等式右侧仍读取i-1层。容量倒序可保证较小下标尚未被当前物品更新;完全背包允许使用当前层dp[c-w],因此可正序。

备考速记

01背包怕拿重,容量倒着走;完全背包能重复,容量顺着走。

倒序枚举在倒序枚举场景中的作用

状态压缩省内存,却也隐藏了新旧层边界。实际编码可以用一个小规模暴力枚举作为对照测试,尤其检查单件物品不能重复和容量边界。

拓展

同类题怎么考

  • 判断0/1背包一维循环方向。
  • 从错误更新结果识别物品被重复使用。
倒序枚举在软件设计师软考中的考法

看到“每件最多一次”先写二维来源,再判断一维数组需要倒序保护旧值;不要直接凭印象选循环方向。

解题思路

拿一件重量3、价值5的物品和容量6试算。若正序,先得到dp[3]=5,更新dp[6]时又读取刚写好的dp[3],结果变成10,相当于同一件物品拿了两次。倒序先算dp[6],读到的是上一轮dp[3],就不会重复。

考点定位

0/1背包一维更新通常倒序,完全背包允许重复选取时通常正序。方向差异来自状态依赖,不是死记的代码格式。

易错提醒

  • 外层先枚举容量、内层枚举物品,改变了状态语义。
  • 倒序边界写成c> w,漏掉容量恰好等于物品重量的状态。
  • 把空间压缩带来的O(C)误写成时间复杂度也降低。

备考提示

  • 用单件物品、容量为两倍重量的反例检验循环方向。
  • 写转移前先说清dp[c]表示处理到哪一件物品后的最优值。

你可能还想了解

  • 0/1背包正序会发生什么?
  • 完全背包为什么可以正序?
  • 一维dp怎样保证物品只选一次?

本文小结

0/1背包一维化后倒序枚举容量,能保证转移来源仍是上一层状态,避免同一轮重复使用当前物品。