题目大意:
给定一个正整数数列(长度小于10万),请你划分成若干段,使得$latex sum[1]>=sum[2]>=$ … $latex >=sum[k] $ 。
求最大的段数,即max(k)。
如 $latex 10 {\ } 10 {\ } 1 {\ } 9 $,即划分成$latex |10 | 10 | 1{\ } 9 | $ 使得 $latex 10>=10>=(1+9)$
题解:这题和经典的最长非降子序列非常像,但是规则变成了子段和非降。细细一想,还真难啊。首先不难想到一个贪心的算法——假设最后一段只取最后一个,然后从后往前扫描,遇到大于等于前一段,则划分一段,接着向前扫描。然而,反例很快就被找出了,比如说我给的例子……
接下来搜索到了如下一个算法:
用$latex g[i] $表示$latex i-n$的数字所能划分出的最大段数,$latex f[i] $表示当$latex g[i] $取到最大值时,最左段的最小和。那么不难发现递推规则如下
设$latex j>i$,则当$latex g[j]+1>g[i] $且 $latex sum[i..j-1]>f[j] $时,
$latex f[i]=sum[i..j-1] $ 而 $latex g[i]=g[j]+1 $
或者是$latex g[j]=g[i] $且$latex sum[i..j-1]<f[i] $且$latex sum[i..j-1]>f[j] $时(即同样高度,最左段的和更小)
$latex f[i]=sum[i..j-1] $
由于$latex g[i]$函数是非升的(显然,我们只要把第$latex i$个数字放到最左边一段去,就可以构造出一个段数为$latex g[i+1] $的方案),而$latex sum[i..j]$随着$latex j $的增长而递增的(左端点固定 ,右端点递增,和肯定递增)。那么我们从小到大枚举$latex j $,第一个能够转移的j必然就是最优的。因为此时$latex g[j]>=g[k](k>j) $,且$latex sum[i..j-1]<=sum[i..k](k>j-1) $。
于是我们就得到了一个$latex O(n^{2})$的算法。然而题目中的n高达十万,所以我们还得继续优化。
设$latex sum[i]=sum[1..i] $,则转移条件是$latex sum[j-1]-sum[i-1]>=f[j] $且 min(j),我们把$latex sum[j-1]$移到等式右边,就变成了$latex -sum[i-1]>=f[j]-sum[j-1]$,由于i是递减的(我们从后往前做),所以$latex -sum[i-1]$是递增的,所以当某个$latex j$,使得$latex f[j]-sum[j-1]<=-sum[i-1] $,那么所有的对于所有小于$latex i$的都会满足。于是对于所有的$latex f[k](k>j)$,都没有必要保留了。于是,我们可以用一个双向队列来维护。复杂度降到了$latex O(n)$。
可是,有一点我们忽略了,就是这个算法是基于一个猜想的,那就是同一个数列所有划分成 n 段的方案中最小最左段和长度必然大于等于划分成 $latex n+1 $ 段的最小最左段和。否则,可能会出现这样一个情况,由于我们$latex f[i]$是基于划分成$latex g[i]$段的,假设$latex [i..n] $划分成$latex g[i]-1$段的方案中,最小最左段和为$latex w$。若$latex w<=sum[1..i-1]<f[i]$,那么我们就会漏掉从i处断开,划分成$latex g[i]$段着一种方案。若$latex g[k](k>i)$都小于$latex g[i]-1$,那么我们就得不到正确答案了。
所以我们必须证明$latex w>=f[i] $。
即将任意一个数列,划分成n段的最小最左段和$latex s_n$大于等于划分成$latex n+1$段的最小最左段和$latex s_n+1$。
我们用数学归纳发来证明,首先显然$latex s_1>s_2 $。
假设$latex s_k>s_k+1$,那么我们考虑如下一张图:

图1
假设我们把数字$latex x $看作数轴上长度为$latex x$的线段,那么原问题等价于在这一连串竖线中选取若干个,使得隔开的区间长度非升。
我们害怕出现的就是如图所示$latex C $部分>$latex A $的情况。
如果出现$latex C>A $的情况,我们就沿虚线重新划分。那么就变成了如图2的情况。

图2
我们将$latex D$段和$latex E$段合并。那么构造出了一个新的$latex k+1$方案。其中$latex A=C$。我们把$latex A$和$latex C$去掉,那么就变成了一组$latex k-1$和$latex k$的方案。由已知条件得$latex B>=D+E$。又因为$latex C=A>=B>=D+E$所以新方案也是合法的,但是最左段和(即A部分)比原来的要小了。于是和已知条件矛盾。
所以图一中的$latex A>=C$。于是命题得证。
特别鸣谢:无所不能的刘城同学(Tongji) 总有有趣题目的陈聪同学(ZJNU)