以下均以 01 背包举例。
状态表示将每一个状态看作一个集合集的属性。
\(f[i,j]\) 表示前 \(i\) 个物品中总体积为 \(j\) 的物品集合集的元素大小和的最大值(属性)。
\(e.g.\)
\[id:1,2,3\]
\[w_i:4,5,9\]
\[v_i:6,8,7\]
\[f[3,9]\to\{\{1,2\},\{3\}\}\]
其中 \(\{1,2\}\) 的价值和最大,为 \(6+8=14\),故 \(f[3,9]=14\)
常见的属性有:大小、最值、和、乘积、异或和……
状态转移对集合集中集合的划分。
将 \(f[i,j]\) 的集合集划分成包含 \(i\) 物品的集合和不包含 \(i\) 物品的集合。
两种情况分别对应 \(f[i-1,j]\) 和 \(f[i-1,j-w_i]+v_i\)。
所以状态转移方程为 \(f[i,j]=\max(f[i-1,j],f[i-1,j-w_i]+v_i)\)。
\(e.g.\)
\[id:1,2,3,4\]
\[w_i:4,5,9,8\]
\[v_i:6,8,7,1\]
\[f[4,13]\to\{\color{blue}{\{1,3\}},\color{red}{\{2,4\}}\}\]
蓝色为不含 \(i\) 的,红色为含 \(i\) 的。
再思考,可以用滚动数组优化空间复杂度。