do_while_true

一言(ヒトコト)

「题解」ARC126D Pure Straight

状压 dp + 费用提前计算。

考虑假如已经确定好了选出那些数(称作标记点),计算一下代价。

毛估估贪心就是先让它们尽量靠中间聚在一起,然后内部再算算逆序对。

尝试把这个东西均摊到每一个位置上,首先是让它们聚在标记点的中位数附近,那么每一个非标记点的代价就是左右两侧标记点个数的 \(\min\)(有这么多标记点要跨过它)。

对于标记点内部的交换,那就是算下逆序对。

这里要将代价均摊到每一个位置上是为了方便 dp 的过程中每加入一个点来计算代价,比较类似费用提前计算的思想。

从前往后枚举 \(i\),设 \(f_S\) 为考虑标记点集合是 \(S\) 的代价,转移的时候枚举当前这个是否是标记点:

  • 标记点:代价为以它为结尾的逆序对个数;
  • 非标记点:\(\min(\operatorname{popcount}(S),k-\operatorname{popcount}(S))\),左右两侧标记点个数的 \(\min\)

Code

posted @ 2022-11-05 10:02  do_while_true  阅读(45)  评论(0编辑  收藏  举报