分组背包循环顺序的正确性
核心代码
for (int k = 1; k <= ts; k++) //循环每一组
for (int i = m; i >= 0; i--) //循环背包容量
for (int j = 1; j <= cnt[k]; j++) //循环该组的每一个物品
if (i >= w[t[k][j]])
dp[i] = max(dp[i],
dp[i - w[t[k][j]]] + c[t[k][j]]);
//像0-1背包一样状态转移
关于循环顺序的正确性。
正确的分组背包:
- 先循环每组
- 再循环容量
- 最后是组员
- -乍看之下,2-3步好像可以倒置,因为都是把每一个组员做一遍状态转移。
- -关键在第二个循环,第二个循环之所以是从m到0,就是为了避免只能用一次的组员被反复使用(见01背包),而这里是从一组里面选一个,一组就相当于01背包的一个物体,只不过循环k次找最优而已。
- -如果倒置,就会变成每个组员都被当做一个物体,让分组变得无意义,退化成01背包了。