凸优化杂题 2025 暑期
A-珠宝
注意到每一类珠宝大小都很小,按大小分类,注意到背包中,下标膜 \(C_i\) 相同的位置,选取多少个珠宝是具有决策单调性的,因此采用分治优化即可。
B-gym102586B
最优疏散策略一定是同时往左右走,先占据距离为1的,然后占据距离为2的……直到所有人都安排完毕。
经过适当的预处理,我们可以 \(O(1)\) 计算出 \([L,R]\) 中点 \(x\) 的疏散代价。
然后考虑到,\(x\) 本质只与 \(L,R\) 更靠近那一个有关系。
不妨设更加靠近 \(r\),则设代价为 \(f(x,r)\),则相当于要找出 \(\max_{(l+r)/2\le x\le r} f(x,r)\)
观察计算过程,\(f\) 满足四边形不等式,因此具备凸性。
则对于不同的 \(r\),若其决策范围都相同,则最优决策点随 \(r\) 增加而单调。
考虑如何解决决策范围相同这个事情,这是批量处理询问的关键。
考虑将 \(([(l+r)/2,x],r)\) 拆到线段树上,然后对于线段树上一个节点上所有的 \(r\),其决策范围都是线段树的这个区间,那么将 \(r\) 排序,跑分治优化决策单调性 dp 即可。
利用线段树找到多个询问的共同决策范围统一处理
另一半翻转过来做一次就行。
C-gym105657L
设 \(w(l,r)\) 是 \([l,r]\) 升一个角色的贡献减去代价。
那么稍加分讨可以发现对于 \(i<j<k<l,w(i,l)+w(j,k)\le 1+w(i,k)+w(j,l)\)
只有刚好卡住等级档位的时候会出现 \(+1\) 的情况。
怎么办呢?这不能够应用四边形不等式了。
如何规避这种卡档情况?一个技巧就出来了合理修改贡献函数,让其满足四边形不等式,这样可以方便我们找到最优决策,但同时要在不影响转移的情况下
那么,将 \(w'\) 卡档的部分当小数来处理,那么就一定满足四边形不等式了。
转移的时候就向下取整即可。
这样的正确性如何保证呢?
设 \(i<j<k<l\),根据 \(w(i,j)+w(k,l)\le 1+w(i,k)+w(j,l)\)
则 \(dp_{i}+w(i,k)-(dp_j+w(j,k))+1\ge dp_i+w(i,l)-(dp_j+w(j,l))\)。
若在 \(k\) 时,决策点 \(i\) 严格劣于 \(j\),也即 \(dp_i+w(i,k)<dp_j+w(j,k)\implies dp_j+w(j,l)\ge dp_i+w(i,l)\)
那么在后面 \(i\) 不会比 \(j\) 优,因此具备决策单调性。
又因 \(w’\) 满足四边形不等式,那么借助 \(w'\) 进行二分队列的维护即可。
四边形不等式中只最多相差1时,可以保证严格优出现在严格劣后面,但相等的位置可以不连续的出现。
通过对贡献函数引入小数去掉这个限制,得到符合四边形不等式的新贡献函数,就可以正常二分决策点了。
而我们维护的这个决策点,也必为最优决策点之一。
D-ABC383G
注意到 \(k\) 很小,且原问题的 dp 数组应当具备凸性。
为了解决距离 \(k\) 的限制,考虑分治做闵可夫斯基和。
具体地,设 \(f(l,r,i,j)\) 表示只考每个块起点在区间 \([l,r]\) 的情况,\(l,r\) 分别距离最近的块头长度为 \(i/j\),对 \(k\) 取 \(\min\)。
合并时使用闵可夫斯基和即可。
\(O(nk^3\log n)\)。
E- QOJ2211
神秘题目,有关结论证明至今不会。
注意到本题中相当于邮局的环形版本。
考虑找到最优的开头?发现这太困难。
一个神奇结论是,对于任意开头的一个分段方案,最优方案的分割点,恰好每一段存在一个。
这个不会证明,感性理解是,你现在都分出来一段,你最优的方案是将其完全包含在某一段里面,分开后应该会更优。
那么,结合原凸性结论,可以猜出,对于递增的开头,分割点满足决策单调性。
剩下的怎么做呢?
因此,先利用wqs二分跑出一个方案,然后选取最短的一段,枚举开头计算答案,枚举量最多 \(O(\frac{n}{k})\),因此考虑 \(O(poly(k))\) 计算一个解。
仿照二分处理决策单调性的办法,将这一段的中点取出,依次对后面每一段跑整体二分处理决策单调性,这样就能够得到以它为中点的方案,复杂度 \(O(len)\),也就是段长总和。
然后以每一段选出的分割点分割两段(自己都要算),首段也分成两半(不算 \(mid\)),分治下去计算。
那么总复杂度就还是 \(O((k\frac{n}{k}+k)\log^2 {\frac{n}{k}}+n\log \frac{n}{k})=O(n\log^2 n)\)
参考实现:code
这启发 当每一段的决策点对于第一段的选点具备单调性时,可以通过分治内套决策单调性分治计算出每个第一段选点的解,其实外层分治更类似与整体二分。
F-gym103102A
显然有 \(f_{i,j}=\max(f_{i-1,j-1},f_{i-1,j},f_{i-1,j+1})+jp_i\)
显然归纳得到凸性,那么一次转移的凸壳变化?
\(\max(f_{i-1,j-1},f_{i-1,j},f_{i-1,j+1})\) 就相当于最大值那一段,边界往左往右扩展1,原本的左右段都往左往右平移。
而左段开头被删掉(不允许负数)——这相当于,假设没有左段斜率,则整体往上平移了左段开头斜率的高度
那么删掉的时候高度就加上左段开头斜率。
最后查找开头(其实是每次被弹出的队头的和)。
这很简单,相当于每次加入两个 \(0\),然后扔掉斜率最大的一段,然后整体加。
通过一个整体加标记即可解决。
cin>>n;
for(int i=1,x;i<=n;++i){
cin>>x;q.push(-ad);q.push(-ad);
ans+=q.top()+ad;q.pop();ad+=x;
}
q.push(-ad);q.push(-ad);ans+=q.top()+ad;
G-CF1787H
考虑到, 由于是 \(max\) ,所以可以将 \(a_i,b_i-k_it\) 拆为两个决策,对于每个课程选择其一进行操作。
而对于选择第二个的所有课程,显然是按照 \(k\) 递减损失最小。
所以按照 \(k\) 降序排序,设 \(f_{i,j}\) 为在前 \(i\) 节课程里,选了 \(j\) 个第二个决策的最优答案。
\(f_{i,j}=\max(f_{i-1,j}+a_i,f_{i-1,j-1}+b_i-k_ij)\)
应用归纳法,可知其具备凸性。
考虑其变化?为了简单起见,不妨改写dp为:
这样就只剩下平移和改斜率了。
画图可知,其前面一段采用平移,后面一段采用修改斜率,在两段中间插入一个分界点 \(k_ij-(b_i-a_i)\) 来衔接,满足 \(k_ij- (b_i-a_i)\) 是大于先前的第 \(j\) 段斜率的,且 \(j\) 最大。
这些画图都可以分析到。
那么就可以用平衡树区间加来维护凸壳了。
H-CF1534G
首先转曼哈顿,这样就变成了坐标差绝对值的和,然后你每次 \((x-1,y-1),(x-1,y+1)\to (x,y)\),起点 \((0,0)\),这就要求了 \(x,y\) 同奇偶。
显然对于 \((x_i,y_i)\) 你走到了 \(x_i\) 之后再激活他是不劣的,所以我们按照 \(x\) 排序,有如下 \(dp\):
对于后半部分的式子,在凸壳上其实相当于将最小值点左侧向左,右侧向右平移 \(x_i-x_{i-1}\) 个单位长度,然后将最小值变成一个斜率为零的段。
于是可以利用一个大根堆 \(L\) 和一个小根堆 \(R\) 维护斜率为零的段的左侧点和右侧点,同时记录全局标记 \(dl,dr\) 表示当前平移长度。
每次我们讨论 \(y_i\) 的位置。
-
\(y_i\) 位于斜率为零的段上
左侧斜率变化,右侧斜率变化,\(L,R\) 里都插入 \(y_i-dl,y_i+dl\)(注意懒标记是全局的)
-
\(y_i\) 位于斜率为负的段上
这时候 \(L\) 里最大的点移动到正段,也就是 \(R\) 里加入 \(L\) 的最大值,同时后面的图像也向上平移了那么多,增加答案
-
\(y_i\) 位于斜率为正的段上
类似上一情况处理即可。
I-qoj8362
相当经典的题目,在2024/9/30的noip模拟赛曾作为T3出现。
首先考虑将怪分类:分为打了加攻和掉攻的。
显然,加攻怪应当按初始值要求从小打到大,不妨设这个答案是 \(A_i\),打 \(i\) 个的最小初始值。
掉攻怪,假设存在一个集合 \(S\),里面的怪都能被打完,则按照打了之后的增加量来打最优。
微扰法证明,设存在 \((a_1,b_1),(a_2,b_2),b_1>b_2\)
则先打 \(1\) 再打 \(2\) 还是反着来对后面的影响是一样的。
问题在于 \(v-a_1+b_1\ge a_2\) 与 \(v-a_2+b_2\ge a_1\) 谁更容易满足?
其实是 \(v+b\ge a_1+a_2\),所以肯定选 \(b\) 大的优先
这个模型很重要
那么第一部分容易,第二部分考虑 \(dp\),将所有怪按照 \(b\) 从小到大 排序,逆着打。
设 \(f_{i,j}\) 为 \([1,i]\) 打掉 \(j\) 个的最小初始体力。
注意到 \(f_{i,j}\le f_{i,j+1},f_{i,j}\le f_{i-1,j}\)
考虑设 \(p_i\) 表示 \(\forall j<p_i,f_{i-1,j}\le b_i\) 的最大值
则:
-
\(j\le p_{i-1}\),\(f_{i,j}\le f_{i-1,j}\le b_i\le b_{i+1}\),说明 \(p_{i+1}\ge p_{i}\)
且 \(f_{i-1,j-1}-b_i\le 0\),而 \(a_i\ge b_i\ge b_{i-1}\ge f_{i-1,j}\)
因此 \(f_{i,j}=f_{i-1,j}\) 已经固定。
-
\(j=p_{i-1}+1\),\(f_{i,j}=\min(f_{i-1,j},a_i)\)
-
\(j>p_{i-1}+1\) 正常转移
那么如何维护呢?
维护 \(p\) 的值,则相当于将凸壳 \(p_i\) 以前的扔掉,然后加入一段斜率为 \(a_i-b_i\) 的线段即可。
则最终同样可以算出 \(B_i\) 为这类的打掉 \(i\) 个的最小初始体力,那么有:
\(ans_k=\min_i \max(A_i,B_{k-i}-s_{k-i})\)
这个可以注意到随着 \(k\) 的增加,\(i\) 应该增加才对,因此具备决策单调性,可分治解决。
当然这一步还有很多做法,如扫描线等等
J-gym104128h
形式化题意就是:给出一颗带边权的树,要求选出 \(k\) 个点 \(a_1\sim a_k\),使得 \(\sum_{i<j}dis(a_i,a_j)\) 最大。
考虑 dp,对于每条边计算贡献,设子树 \(x\) 里选出 \(i\) 个点的最大贡献是 \(f_{x,i}\)
则 \((x,fa_x,w)\) 的贡献就是:\(2wi(k-i)\)
那么 dp 呼之欲出:
其中 \(g\) 是儿子的 \(f\) 做背包的结果。
注意到是简单的合并和二次函数,所以 \(f\) 具备凸性。
那么 \(g\) 的得到是容易的,将子树的凸包合并起来即可。
\(\max(g_{x,i},g_{x,i-1})\) 如何得到?二分凸壳找到零点,扩展一下这个位置(相当于在斜率序列找到位置插入一个 \(0\))
然后 \(2wi(k-i)\) 又如何?
其实是一个全局的斜率序列加等差数列。
使用平衡树维护,合并时采用启发式合并。\(O(n\log n)\)。
注意到维护的上凸壳斜率递减,平衡树是递增的。

浙公网安备 33010602011771号