【CCC2019】 Tourism

题目大意

将一个长度为 nn 的序列分为 nk\lceil \dfrac{n}{k}\rceil 段且每一段的长度不超过 kk,求每一段的最大值的和。

数据范围满足,1kn1061\le k\le n\le 10^6

思路

考虑暴力的 dp,定义 fi,jf_{i,j} 表示前 ii 个分成 jj 段的答案。

fi,j=maxl=iki1(fl,j1+maxr=l+1i(ar))f_{i,j}=\max\limits_{l=i-k}^{i-1}(f_{l,j-1}+\max\limits_{r=l+1}^{i}(a_r))

考虑如何优化这个 dp,显然枚举过程已经是最优,只能从状态上简化。

可以发现这样一个事实,我们之前枚举的大部分状态对于最终的答案都是没有贡献的。借此,我们发现对于 ii,只有 fi,ikf_{i,\left \lceil \frac{i}{k} \right \rceil } 对之后的答案有贡献。证明如下:

  • j<ikj<\left \lceil \frac{i}{k} \right \rceil,那么必定有一段长度大于 kk
  • j>ikj>\left \lceil \frac{i}{k} \right \rceil,由上分析可知后面最少也要 nik\left \lceil \frac{n-i}{k} \right \rceil 段,所以有 j+nik>ik+niknkj+\left \lceil \frac{n-i}{k} \right \rceil >\left \lceil \frac{i}{k} \right \rceil + \left \lceil \frac{n-i}{k} \right \rceil \geqslant \left \lceil \frac{n}{k} \right \rceil 一定不满足。

所以记 gi=fi,ikg_i=f_{i,\left \lceil \frac{i}{k} \right \rceil },根据如上的方程,能够向 gig_i 贡献的只有满足 ikji1i-k\leqslant j \leqslant i-1ik1=jk\left \lceil \frac{i}{k} \right \rceil-1=\left \lceil \frac{j}{k} \right \rceiljj,所以方程为:

gi=maxj=ikk×i1k(gj+maxk=j+1iak)g_{i}=\max _{j=i-k}^{k \times\left\lfloor\frac{i-1}{k}\right\rfloor}\left(g_{j}+\max _{k=j+1}^{i} a_{k}\right)

对于 maxk=j+1iak\max _{k=j+1}^{i} a_{k} 考虑使用单调栈进行求解,对于 gig_i 的区间最大值使用线段树维护,其时间复杂度为 O(nlogn)O(n\log n)

记录详情 - 洛谷 | 计算机科学教育新生态 - luogu.com.cn