AGC046C 题解

blog。好菜啊,不会这题,来写个题解 /kel。


很难直接做,先找一点性质:操作只改变相对顺序,而总数不变。

这启示我们记录每个 \(0\) 前面的极长 \(1\) 连续段长度。记第 \(i(1\le i\le C)\)\(0\) 对应长度为 \(a_i\),就存在下面的等价表述:

每次操作可以选定 \(i,j(1\le i<j\le C)\),将 \(a_i\)\(1\)\(a_j\)\(1\),且始终有 \(\forall a_i\ge0\)

注意到,如果选定 \((p,i)(i,q)\),实际只是 \(a_p\) 少了 \(1\)\(a_q\) 多了 \(1\),可以用一步 \((p,q)\) 代替。于是此时存在操作次数更少的相同方案。

也就是说,每一位要么始终加,要么始终减

不难用 dp 刻画:\(dp_{i,p,q}\) 表示前 \(i\) 个数用了 \(p\)\(+1\)\(q\)\(-1\)\(p\ge q\)),方案数。不难有如下 \(O(n^2 k^2)\) 的转移:

\[\begin{cases}dp_{i,p,q}\gets dp_{i-1,p,q}\\dp_{i,p,q}\gets dp_{i-1,p-t,q} & (1\le t\le x)\\dp_{i,p,q}\gets dp_{i-1,p,q-t} & (1\le t\le \min(q,a_i))\end{cases} \]

\(k\) 很大。但是注意到每个 \(1\) 至多被移动一次。因为移动很多次的话,实际可以一步到位,于是必然存在操作次数更少的相同方案。

所以可以令 \(k\gets\min(k,|S|)\),复杂度就降为了 \(O(n^4)\)。不难前缀和优化至 \(O(n^3)\)


小细节:可以在 \(S\) 末尾添加一个 0,来处理末尾 \(1\) 连续段。

code,时间复杂度 \(O(n^4)\),加上指令集后可以轻松通过。三次方做法懒得改了,反正其他题解有写。

posted @ 2024-08-05 19:48  liangbowen  阅读(3)  评论(0编辑  收藏  举报