2016-5-17模拟测试

  • T1

    • description
      \(n\)个二元组\((a_i,b_i)(1\leqslant i \leqslant n)\)定义\(c_1 = a_1 + b_1,c_i = \max(c_{i-1}, \sum_{j=1}^{i}a_j)+b_i\),求一个排列使\(c_n\)最小.
    • solution
      考场上直接考虑交换两个会不会使最终答案变优,这样就很复杂,直接考虑交换相邻的两个会不会使这个\(c_i\)变小即可,影响的位置只有1个。
  • T2
    裸曼哈顿距离最小生成树。

  • T3

    • description
      一个序列\({a_n}\),请找到一个序列\({b_n}\)使得\(\forall i\)\(a_i \leqslant b_i\),且\(f = \sum_{i=1}^{n}{(a_i-b_i)^2} + \sum_{i=2}^{n}{|b_i-b_{i-1}|}\)最小,输出这个最小值。
    • solution
      考虑\(n=3\)的情况,我们发现只有在\(a_2<\min{a_1,a_3}\)的情况使\(a_2\)才会使答案更优,而且目标函数是二次函数,可以\(O(1)\)求出。
      我们又发现,如果相邻的两个数被改了,那么他们一定被改成了同样的数。
      根据上面两条性质,不妨用\(f_i\)表示在不修改\(i\)的情况下的最小值,那么对于\(j\leqslant i, \max{a_{j+1},a_{j+2},...,a_{i-1}} <= \min(a_i,a_j)\)\(j\)可以更新\(i\)
      而这样的更新次数显然只有\(O(n)\)次,可以用一次单调栈求出。
    • notice
      1.由于\(f_i\)的定义,在具体实现时,我们添加\(a_0, a_{n+1}\)方便处理,他们的值应设为一个极大值。
      2.注意极大值参与运算时溢出的问题。
posted @ 2016-05-17 20:36  Showson  阅读(118)  评论(0编辑  收藏  举报