B
题目链接:2022 省选训练赛 Contest 18 A
题目大意
给你 n 个点,每个点第 i 天的代价是 b[i]+(i-1)a[i]。
然后要你在前 m 天每天选一个点,然后最小化总代价。
思路
首先考虑怎么 DP,观察到如果你选好的一个点集,你可以很容易的得到最优的选的方案。
即按 a i a_i ai 从大到小排,然后每次依次选,这样增长的量就会最小。
我们可以按 a i a_i ai 从大到小排序来 DP,设 f i , j f_{i,j} fi,j 为搞定前 i i i 个,选了 j j j 个的最小费用。
然后每次下一个选或者不选转移,显然超时。
考虑维护每个 f i f_i fi 数组,亦或者说是看一个新的数会产生什么。
然后有一些性质。
首先就是 f i , j f_{i,j} fi,j 的点集必定是 f i , j + 1 f_{i,j+1} fi,j+1 点集的子集,你可以用反证法来得到。
(反正意思就是你不选这个点集的肯定不如 f i , j f_{i,j} fi,j 的点集加上一个数更优)
然后接着就是加入一个数,它能修改的范围一定是一段后缀。
这个也是可以通过反证法得到,根据前面的性质就有了。
那我们就可以通过二分出贡献的后缀。
然后你要支持区间插入,区间加,区间二分,可以用平衡树来实现。
(过程就是维护每个点当前代表的选的个数,以及新选这个需要的费用)
(那你贡献就是一个区间加值,就是后面的一段都要加上你这个 a i a_i ai,因为你每往后一个位置,就多了 a i a_i ai 的费用)
代码
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse"

本文介绍了一种使用平衡树优化动态规划算法的方法,以解决在特定条件下选择点以最小化总代价的问题。通过按特定顺序排序并利用平衡树进行区间操作,实现了高效的解决方案。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



