<min/max,+>卷积与背包优化

【前置知识】

convex 与 concave:这是对于数组的概念。类比函数,下凸就是 convex,上凸就是 concave。

【<min,+>卷积问题】

考虑两个数组 a1n,b1m,定义它们的<min,+>卷积结果 c

  1. |c|=n+m

  2. ci=minj+k=i{aj+bk}

因为普通的卷积是 +,形式类似。所以这种运算就叫做<min,+>卷积。<max,+>卷积的定义是类似的。

这个问题目前没有快于 O(nm) 的解法,但是在特殊情况下可以做一些优化。

【双 convex 情况】

结论:如果 a,b 都 convex,可以 O(n+m) 解决这个问题。

考虑 a,b 的差分数组 Δa,Δb。(Δa1=a1Δai=aiai1
ci 就是在 Δa,Δb 中最小的 i 个数之和。

容易证明,不再赘述。

【单 convex 情况】

结论:如果 a 是任意数组,b 是 convex 的,可以做到 O(nlogm) 解决。

这个情况比上面的复杂很多。我们先定义一下两个函数方便叙述。

fj(x)={(j+i,aj+bi)|1im}

f(x)={(i,bi)|1im}

观察 1:ci 实际上等于 x=i 处,f1n(x) 最低点的值。
观察 2:fj(x)f(x) 的平移。

于是求 c 数组,实际上等价于求 f1n(x) 的下凸壳。下面讲解怎么求。

由观察 2 知 fj(x)fj(x) 最多一个交点(jj 时)。有了这个观察能做什么?

其实这里已经可以用李超线段树做了,不过李超树是 O(nlog2n) 的,我们像四边形不等式的队列那样,进一步优化。

维护队列 q 保存 i1,i2,,ik,表示当前还有用的函数图像有 fi1ik(x)。现加入 fj(x)。若 fj(x)fik(x) 的交点在 fik(x)fik1(x) 的交点左侧,则 ik 没有用了,可以弹出。进行完所有弹出后,假设此时队列末尾元素为 k(如果队列弹空了就直接加入 j)。在 fk(x) 有用的区间内二分,找到第一个 fk(x)fj(x) 的位置 pos。从 pos 往后,fk(x)fj(x)

在具体实现时,除了记录 i1,还要记录它的有用区间 [li1,ri1]。这和四边形不等式的二分队列是一样的。

二分带一个 logm,而函数个数是 n,所以总复杂度是 O(nlogm) 的。

【背包优化】

【01 背包优化】

记总重量为 C,重量种类数为 m,这里给出一个 O(nlogn+mClogC) 的做法。

把物品按重量从大到小排序,同重量按价值从大到小排序。

Ai[j] 表示考虑完前 i 种重量后,选一些物品总重为 j 的最大价值。

Ai1 怎么推到 Ai?设第 i 类重量为 w。用 B[k] 表示在第 i 类中选总重为 kw 的物品(其实就是选 k 个)的最大价值。

观察发现 B[k] 是 concave 的。因为 B[k+1]B[k] 选多一个物品,而且这多的一个物品必然是价值第 k+1 大的物品。再多选一个,就是第 k+2 大的了。以此类推,增长的价值必然递减。

Ai1[j]jmodw 的余数分类,每一类单独与 B 做<max,+>卷积,就能得到对应位置的 Ai[j]。每一类 A 的长度是 CwB 的长度是 w,一共做 w 次(余数分 w 类)。所以复杂度是 O(Cwlogww)=O(Clogw)=O(ClogC)

注意这里不能直接把 B 拓展到长度为 C 的数组,然后拿这个拓展后的数组卷。因为拓展后 B 显然就不 concave 了。

一共 m 种重量,所以复杂度是 O(mClogC)。排序还有 O(nlogn)。总复杂度 O(nlogn+mClogC)

【完全背包优化】

这个优化和<max,+>卷积凸优化没关系。

设最大重量为 D,总重 C,给出一个 O(D2logC) 的解法。基于倍增。

ansi 表示总重为 i 时的最大价值。暴力求出 ans0ans2D,复杂度 O(D2)

有:当 i>Dansi=max|jk|D,j+k=i(ansj+ansk)

进而可以得到:ansjD/2j+D/2anskD/2k+D/2 做一次<max,+>卷积可以得到 ansj+kDj+k+D。我们只需要 O(D2) 的来做这个就够了。

既然 O(D2) 可以从 j,kj+k,那么直接倍增就可以做到 O(D2logC)

posted @   FLY_lai  阅读(256)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示