loading...

[AGC062B]Split and Insert

不是 AGC 怎么做到题题代码短,思维量大的?

链接

Description

给定一个排列 \(A=(A_1,A_2,\dots,A_N)\) 。一开始,排列满足 \(A_i=i\ (1\leq i \leq N)\)。接下来高桥会进行 \(K\) 次操作,操作如下:

  • 任意选择一个 \(k\) ,选择排列最末尾 \(k\) 个元素,将其插入进前面 \(n-k\) 个元素。形式化的,操作之后的排列需要满足:
    1. \((A_1,A_2,\dots,A_{N-k})\) 是一个操作后排列子序列(不要求连续)
    2. \((A_{N-k+1},A_{N-k+2},\dots,A_{N})\) 是操作后排列的一个子序列(不要求连续)

定义所有操作的代价是 \(\displaystyle\sum_{i=1}^{K}k_iC_i\),其中 \(k_i\) 表示第 \(i\) 轮选择的 \(k\)

现在高桥君想问你能否在 \(K\) 次以内将排列变为 \((P_1,P_2,\dots,P_N)\),如果可以输出最小代价,如果不能输出 \(-1\)

  • $ 2 \leq\ N \leq 100 $
  • $ 1 \leq\ K\leq 100 $
  • $ 1 \leq\ C_i\leq 10^9 $
  • $ (P_1,P_2,\dots,P_N)$ 是 \(1\)\(N\) 的排列。
  • 所有输入均是整数。

Solution

倒着考虑,发现一次逆操作为:选一个长为 \(k_i\)\(A\) 的子序列放在最后。最初状态为 \(P\),问它执行 \(K\) 次逆操作能否有序,并输出最小代价。

从值域方向考虑,最后一次逆操作时,应当满足选的子序列值域为 \([1,x]\),剩下的子序列 \([x+1,N]\),且这两个子序列必须有序。这启发我们从值域进行区间 \(\rm dp\)

定义 \(f_{i,l,r}\) 表示 \(i\) 次逆操作后,\([l,r]\) 这一段值域在序列中已经有序的最小代价。

转移:\(f_{i,l,r}=\displaystyle\min_{x=l}^{r}\{f_{i-1,l,k}+f_{i-1,k+1,r}+(r-x)C_{K-i+1}\}\)

边界:\(f_{0,l,r}=\) 值域为 \([l,r]\) 的子序列在 \(P\) 序列中有序。

submission

posted @ 2025-03-20 18:16  goldspade  阅读(13)  评论(0)    收藏  举报