分组背包循环顺序的正确性

分组背包循环顺序的正确性

核心代码

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背包一样状态转移

关于循环顺序的正确性。
正确的分组背包:

  1. 先循环每组
  2. 再循环容量
  3. 最后是组员
  • -乍看之下,2-3步好像可以倒置,因为都是把每一个组员做一遍状态转移。
  • -关键在第二个循环,第二个循环之所以是从m到0,就是为了避免只能用一次的组员被反复使用(见01背包),而这里是从一组里面选一个,一组就相当于01背包的一个物体,只不过循环k次找最优而已。
  • -如果倒置,就会变成每个组员都被当做一个物体,让分组变得无意义,退化成01背包了。

分组背包题目:
https://www.luogu.com.cn/problem/P1757

我的个人hexo博客.

猜你喜欢

转载自blog.csdn.net/osusoer/article/details/105204875