使用单调队列优化的 O(nm) 多重背包算法 (转)

作者: zqqian 分类: ACM,算法 发布时间: 2017-04-26 20:33

最近在翻看国家队集训论文的时候发现提到了使用单调队列来优化多重背包,于是找到了这个博文,觉得不错,转发过来慢慢理解

解析

令 c[i] = min(num[i], j / v[i])

f[i][j] = max(f[i-1][j-k*v[i]] + k*w[i]) (1 <= k <= c[i]) 这里的 k 是指取第 i 种物品 k 件。

如果令 a = j / v[i] , b = j % v[i] 那么 j = a * v[i] + b.

这里用 k 表示的意义改变, k 表示取第 i 种物品的件数比 a 少几件。

那么 f[i][j] = max(f[i-1][b+k*v[i]] – k*w[i]) + a*w[i] (a-c[i] <= k <= a)

可以发现,f[i-1][b+k*v[i]] – k*w[i] 只与 k 有关,而这个 k 是一段连续的。我们要做的就是求出 f[i-1][b+k*v[i]] – k*w[i] 在 k 取可行区间内时的最大值。

这就可以使用单调队列优化。

例题:HDOJ – 1171
原文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注