ZR24 Summer A Day5 | DP
CF808E Selling Souvenirs 加强
\(n\) 个物品的背包,\(V_i\in[1,4]\),\(w_i\le 10^9\),\(n\le 10^5\)。
基于值域枚举后进行贪心
观察到 \(\operatorname{lcm}(1,2,3,4)=12\),于是我们可以将重量为 \(1,2,3,4\) 的分别打包为重量为 \(12\) 的。比如 \(12\) 个重量为 \(1\) 的可以凑成一组,其他同理。但是会出现零散的也就是无法打包的部分,由于值域很小,直接枚举即可。
设 \(cnt_i\) 表示重量为 \(i\) 的拿了多少个。我们枚举 \(cnt_1 \bmod 12\),\(cnt_2\bmod 6\),\(cnt_3\bmod 4\),\(cnt_4\bmod 3\)。接着选最大的 \(cnt_1\bmod 12\) 个 \(1\),\(cnt_2\bmod 6\) 个 \(2\)...
这么处理之后剩下的就都是重量为 \(12\) 的大组了,可以贪心去取。代码。
分治-闵可夫斯基和
直接背包没有凸性,但是在 \(\bmod 12\) 意义下的每一个剩余系都具有凸性。
设 \(f_{i,k}\) 表示选了 \(12\times k+i\) 体积的物品,可以得到的最大价值。
我们可以采用分治,每个区间维护上述 \(12\) 的个凸函数,然后左右区间进行 \(12\times 12\) 次合并。
假设现在合并的是左 \(a\) 和右 \(b\),那么合并到大区间后就是 \(\to (a+b)\bmod 12\)。对于 \(k\) 那一维度可以做闵可夫斯基和。
CF1787H Codeforces Scoreboard
假设已经知道了哪些用 \(a_i\),哪些用 \(b_i-k_i\times t\),那么我们直接按照 \(k\) 从大到小排序,先选 \(k\) 大的,再选 \(k\) 小的,最后选那些 \(a_i\) 的就能保证最优。但是我们现在不知道选择了什么,可以先按照 \(k\) 降序排序,然后 dp,这样子就可以在决策的过程中符合上述贪心操作了。
\(dp_{i,j}\) 表示前 \(i\) 个题用了 \(j\) 个题是 \(b_i-k_i\times t\) 形式的所用最小时间。
\(dp_{i,j}=\max(dp_{i-1,j}+a_i,dp_{i-1,j-1}+b_i-k\times j)\)。
这个形式很明显就是一个整体 dp 的形式,应该是要用大 DS 维护。
感性理解一下,这种加一个斜率为负的一次函数和常数取 \(\max\) 的东西应该是凸的。
打表/根据取 \(\max\) 的特性,可以得到 \(dp_{i,j}\) 对于每个 \(i\) 关于 \(j\) 是上凸的。
考虑 \(dp_{i,j}\) 的决策,
假设我们选择前者,就要满足
由于 \(dp\) 是上凸的,所以等式左边应该是单调递减的。等式右边也是单调的,所以可以直接二分找到交点。或者可以看成一条斜率为 \(-k_i\) 的直线去切 \(dp\) 的凸包。
假设我们找到了交点为 \(j=x_0\),
那么对于 \(j\le x_0\),我们要对于 \(dp\) 整体加 \(a_i\)。
对于 \(j\ge x_0\),我们要对于 \(dp\) 平移(因为转移脚标是 \(j-1\to j\))之后加一个一次函数 \(-k_i\times j+b_i\)。
有点难做,我们不妨维护其差分数组 \(g_{i,j}=dp_{i,j}-dp_{i,j-1}\)。
思考差分的变化,
前一段的区间加就是差分的单点加减。然后交接点的地方处理要小心点,就是对于 \(j=x_0+1\),此时 \(dp_{i,x_0}=dp_{i-1,x_0}+a_i,dp_{i,x_0+1}=dp_{i-1,x_0}+b_i-k_i\times j\),\(g_{i,x_0+1}=b_i-a_i-k_i\times j\)。
对于 \(j=x_0+2\),\(dp_{i,x_0+2}=dp_{i-1,x_0+1}+b_i-k_i\times (j+1)\),\(g_{i,x_0+2}=g_{i-1,x_0+1}-k\)。对于 \(j\) 更大的情况同理,这一部分就是平移之后后缀加一个 \(-k\)。
所以我们可以发现对于 \(g\) 的操作就是单点加,单点插入 (\(x_0+1\) 处),还有后缀加。
可以用平衡树维护,时间复杂度 \(O(n\log n)\)。
ABC305Ex Shoji
先思考段内权值,对于同一段内如何排序,可以用邻项交换法,发现按照 \(\dfrac{B}{A-1}\) 从
然后本题显然可以用 WQS 二分。
发现这个函数复合的增长是十分迅速的,至少也是 \(2^x\) 级别的,所以我们可以只取前 \(30\) 个点作为决策点。
P9266 [PA 2022] Nawiasowe podziały
wqs二分后,广义笛卡尔树上 DP。
环状邮局
如果随机化断环为链的话,是单次采用决策单调性分治是 \(O(nk\log n)\),发现断点的个数至少是 \(\dfrac{n}{k}\) 个的,于是我们随机 \(O(\dfrac{n}{k})\) 次,所以最后是 \(O(n^2\log n)\) 的。环状邮局
CF1842I Tenzing and Necklace
如果链状的,直接WQS二分+单调队列就行了。
先构造一组方案,然后根据相交 > 包含,发现其他方案的点必须是交错在初始方案中的,决策单调性分治。
gym102268J
考虑如果两端中 \(sum_i-sum_{i+1}>\max a\),我们可以不断把 \(i\) 段末尾的数放入第 \(i+1\) 段,直到出现合法。这种调整法太慢了。
我们发现如果能做调整,最后的 \(\sum sum_i^2\) 会变小,那么 \(\sum sum^2_i\) 最小的时候,就是不能调整了。于是可以 WQS 二分,然后斜率优化。至于构造方案可以记录前缀 \(\max \min\) 拼接。
P9338 [JOISC 2023 Day3] Chorus
寻找性质的 dp 好题。首先一个序列能划分为若干个合唱队的充要条件是第 \(i\) 个 \(A\) 在第 \(i\) 个 \(B\) 前面。
考虑划分出 \(k\) 个合唱队,注意到第 \(i\) 个 \(A\) 一定和第 \(i\) 个 \(B\) 一组,所以匹配形式一定是第 \([l,r]\) 个 \(A\) 和第 \([l,r]\) 个 \(B\) 放在一组,于是我们需要对于 \([1,n]\) 划分成出 \(k\) 个区间 \([l,r]\),然后让第 \(l∼r\) 个 \(A\) 在第 \(l∼r\) 个 \(B\) 前面。
设 \(f_{i,j}\) 表示前 \(i\) 个位置里面划分出了 \(j\) 个区间,可以得到
设 \(w(l,r)\) 表示区间 \([l,r]\) 的调整代价,不难发现设第 \(i\) 个 \(A\) 前面有 \(c_i\) 个 \(B\),那么有$$w(l,r)=\sum\max(c_i-l+1,0)$$
直接暴力 dp 是 \(O(n^3)\) 的。可以发现 dp 的第二维关于 \(j\) 是具有凸性的,可以用 wqs 二分来去掉这一维度。
同时 \(w\) 是满足四边形不等式的,使用二分队列维护,时间复杂度 \(O(\log n\log V)\)。会被卡常。
其实 \(w\) 是可以去掉 \(\max\) 的,可以发现 \(w\) 是单调的,所以记 \(p_l\) 表示最小的位置满足 \(c_{p_l}-l+1\ge 0\),拆掉 \(\max\) 之后就是一个斜率优化的形式了,可以线性求解。于是总的时间复杂度就是 \(O(n\log n)\)。
gym102331J
发现 \(f_{i,j}\) 是凸的,可以树链剖分。
也可以模拟费用流。
Gym102331H Honorable Mention
ZR2842
我们对于 \(0 1\) 做 \(+-1\) 前缀和。我们发现一个长度 \(>1\) 的 \(1\) 段是可以拆成多个小段的。
LOJ6289. 花朵
LOJ3661. 「2021 集训队互测」蜘蛛爬树
可以发现 \(u_x\to v_y\) 的路径必定 \(u_x\to w_x\to w_y\to v_y\),对于 \(w\) 的位置进行分类讨论,在 \(\mathrm{LCA}(u,v)\) 之内还是之外,将距离改为深度推式子。
假设 \(w\) 在 \(\mathrm{LCA}\) 之内且和 \(u\) 一个子树,那么就是
在确定 \(\mathrm{LCA(u,w)}\) 之后可以发现这是对于 \(w\) 相关的一个凸包。暴力跳 \(\mathrm{LCA}\) 的复杂度肯定是不对的,可以按照 P11330 [NOISG 2022 Finals] Grapevine 里面的 trick 暴力跳重链查询。
对于 \(w\) 在外面的情况同理。
可以维护凸包或者直接使用李超线段树来求解。
CF1534G A New Beginning
水题,不知道为啥评黑。
首先将切比雪夫距离转化为曼哈顿距离,就是单次的代价就是 \(\lvert X-x_i\rvert+\lvert Y-y_i \rvert\),其中每次只能往右上/右下走。我们的行走是没有代价的,所以肯定是走到一个尽可能优的点,对于任意路径发现曼哈顿距离最近的时候是走到某个点垂直于 \(x\) 轴的线上。
据此进行 DP,设 \(dp_{i,j}\) 表示在 \(x_i\) 位置的上纵坐标为 \(j\)。列出转移方程,
这是一个每次加上一次函数的图象,由于取 \(\min\) 操作,很显然其是下凸的函数,可以使用 Slope Trick 进行优化。
我们使用两个堆维护下凸函数的左半边和右半边,记为 \(L,R\)。
令 \(l=x_i-x_{i-1}\),首先 \(dp_{i-1,k}\) 和 \(|y_i-j|\) 是独立的,我们先处理前者,也就是\(\min\limits_{\lvert k-j\rvert\le l} dp_{i-1,k}\),观察函数图象,只需要对于 \(L\) 向左平移 \(l\),对于 \(R\) 向右平移 \(l\) 即可,这个打一个全局移动的标记就行了。然后就是全局 \(+|y_i-x|\) 的操作,分类讨论 \(y_i\) 与 \(L\) 最右端还有 \(R\) 最左端的大小关系,然后往堆中加入转折点(代表斜率变化)即可。由于求的是最小代价,我们直接维护下凸函数斜率 \(=0\) 的那一段的高度(函数值)即可。
时间复杂度 \(O(n\log n)\)。
P9521 [JOISC 2022] 京都观光
考虑 \((l,x)\to(r,y)\) 的路径可以 \((l,x)\to (r,x)\to (r,y)\),也可以 \((l,x)\to (l,y)\to (r,y)\)。
前者的代价是 \(b_x(r-l)+a_r(y-x)\),后者的代价是 \(a_l(y-x)+b_y(r-l)\)。前者比后者更优需要满足
可以发现这可以放到两个凸包上求解。单调栈建立对于 \(a,b\) 的凸包之后,每次选择斜率写的一边走。由于上述式子可以放到到任意局部,所以这是对的。
其实本质就是对于两个凸包进行闵可夫斯基和。

浙公网安备 33010602011771号