CF1579G - Minimal Coverage
题目描述
- 给出 n n n 条线段,第 i i i 条线段长度为 a i a_i ai。
- 现在要求将所有线段按照给出的顺序依次放置在一个无限长的数轴上
并且满足当前放置线段的起点等于上一条放置线段的终点。 - 初始线段起点为 0 0 0
- 现在要求所有线段的覆盖的长度(即线段的并)最短
- t t t 组数据, 1 ≤ t ≤ 1000 1 \leq t \leq 1000 1≤t≤1000,保证 ∑ n ≤ 1 0 4 \sum n \leq 10^4 ∑n≤104
- 对于每组数据 1 ≤ a i ≤ 1000 , 1 ≤ n ≤ 1 0 4 1 \leq a_i \leq 1000,1 \leq n \leq 10^4 1≤ai≤1000,1≤n≤104
分析
很不错的一道题,虽然没有多难,但是题目很多做法和细节都值得思考
做法1:DP
首先可以把所有线段想象成若干次跳跃,那么可以想到以数轴长度作为状态转移的DP单次转移都是 O ( 1 ) O(1) O(1) 的。
具体看题目要求,我们要求线段的覆盖距离最短,那么需要记录一个到达过的最左距离 L L L 和最右距离 R R R ,和当前在位置 p o s pos pos,但是显然我们受数据限制没法开这么多维记录。
思考这个问题,我们首先可以把跳跃的范围缩短到 [ − m a x { a i } , m a x { a i } ] [-max \{a_i \},max \{a_i \}] [−max{ ai},max{ ai}],这里不做严格证明,并且我不知道怎么证在下述算法运行时这个结论成立。
简单的论述一下:假设我们这次跳跃的位置的绝对值第一次超过 m a x { a i } max \{a_i \} max{ ai},那么上一次的位置处在数轴相同一侧 [ 1 , m a x { a i } ) [1,max \{a_i \}) [1,max{ ai}) 的位置。那么如果我们往相反一侧跳跃,就不会超过上述范围,因此我们可以有效的把长度压缩至 [ − 1000 , 1000 ] [-1000,1000] [−1000,1000]