首先,本题很容易得出一个暴力 dp
O(n2) 的做法:
dpi=j=0mini−1dpj+cost([aj+1,aj+2,…,ai])。但显然这不够优秀。
接下来介绍两个神奇的结论。只需了解任意一条就可以解决 D1,但是只有将这两条都掌握才能解决 D2。
D1 解法 1(性质 1)
f(a)≤2log2an 考虑一种每个子段的
cost 都为
1 或
2 的贪心做法。因为你在划分时根据贪心策略显然会将第一个
<2an 的数划为下一段的右端点,所以不难发现
cost=2 的子段数量显然不超过
log2an 个。
这样答案范围直接缩小到了
128 以内。我们可以设置一个
ri 维护
f([a1,a2,…,ak])≤i 的最大
k 值,省去原暴力做法中许多不必要的转移,实现
O(nlog2V) 的 dp。
D1 解法 2(性质 2)
存在一种最优解,使得划分出的每一个子段的
cost 值
≤3。这是因为,对于任意一个
cost 值
=x(x≥4) 的子段都可以拆成一个
cost 值
≤2x 的子段和一个
cost 值
≤2 的子段。由于
2x+2≤x,这样做显然是不劣的。
这样,就可以考虑使用数据结构解决 D1 了,但相对于解法 1 而言比较繁琐,不再介绍。
D2 解法
模仿 D1 解法 1,我们将
dpi,j 的定义修改为使得
f([ak,ak+1,…,aj])≤i 的最小
k。显然,
dp0,j=j+1。
当
i=1,2,3 时,
dpi,j 可以通过使用线段树计算出来。
根据上述两条性质可知对于
∀i≥4,dpi,j=k=1min3(l=max(dpi,j−k−1,0)minj−1dpl,k)。对
i=1,2,3 时的
dpi,j 分别开一个 ST 表实现
O(1) 查询区间查询最小值即可。
答案即为
i=1∑128j=1∑ni(dpi,j−dpi−1,j)。时间复杂度
O(n(log2n+log2V))。