正睿 NOIP 十连测
B
有 \(n\) 个数 \(a_1 \sim a_n\)。初始有一个 \(x = 1\),每次需要将 \(x\) 变为某个 \(i\),花费代价为 \(\min(|i - x|, n - |i - x|)\),且 \(a_x \le a_i\)。问访问所有 \(i\) 需花费的最小代价。(初始的 \(1\) 不算访问。)
肯定按照 \(a\) 从小到排序离散化。令 \(dp_{i, j}\) 表示访问完 \(\le i\) 的数最后停在 \(j\) 的最小代价,显然有 \(a_i = j\),所有状态数是 \(O(n)\) 的。
考虑转移,假设到达的第一个 \(i + 1\) 的位置是 \(x\),分 \(x < j\) 与 \(x > j\) 分开转移(双指针),将两种花费方式拆开算上即可。因为转移是一段前缀和一段后缀,稍微优化一下即可。
而到达 \(x\) 后,最后一个到达的为 \(i + 1\) 的位置在 \(x\) 左右各有一个,这样才能保证所有 \(a_y = i + 1\) 的 \(y\) 的位置都走到。
时间复杂度:\(O(n \log n)\)。瓶颈在于离散化。
常规 DP 题。
C
鬼畜分类讨论加上组合数题。似乎需要用到亿点点生成函数。(范德蒙德)
分讨第一刀横切与竖切,分成两个子问题计算,注意不要算重!!(例如第一刀与第二刀都是横切。)
D
类似 NOI2016 优秀的拆分,枚举 \(len\),一段一段的考虑。需要用到 SA 和线段树。贼恶心。
时间复杂度是 \(O(n \log n)\)。