[Codeforces is All You Need] ER 145 D (1809D) - Solution
题目简述
给定长度为的
串,每次操作可以删除任意元素(代价为
)或交换相邻元素的位置(代价为
)。求将该串变为非递减串的最少的代价(空串也是非递减的)。
原题目链接:https://codeforces.com/contest/1809/problem/D
思路
每次操作代价的数值是最扎眼的。足够大并且
足够小的奇怪数值,保证了:无论进行的操作种类如何,总操作次数越少越好。这是因为至多
次删除就一定能把串变成非递减的,而此时
(差异凑不够一次操作),因此操作次数在优化中占据了绝对的主导地位。
另一个简单的事实是,非递增串的前缀必然也是非递增的。如此优良的性质,不令表示将
变为以不以
结尾的非递增序列所需的最小代价,是很不划算的。(以
结尾则是平凡的,答案是
,其中
表示
中
的数目。)
首先是平凡的边界。
对于的情形,转移是非常容易的。我们可以不删除
,于是:
其中后一项是将全变为
的代价。另外,此时我们没有任何必要删除
。
对于的情形,我们必须要把它除掉。如果直接删除,有:
如果使用交换,事情稍微复杂起来了,我们需要考虑一下交换操作在什么时候才是有意义的。假设,且所有
的下标序列依次序为
。如果对
交换后进行了删除,那么需要的操作次数
,且与直接删除完全等价,因此这种行为是无意义的。这意味着如果要对
进行交换,必须贯彻到底,只对其使用交换。在这种前提下,为使序列非递减,假设需要删除
(
),那么仅仅由于
带来的操作次数为:
如果,那么显然不如直接将
个
全部删除。
如果,这意味着:
用人话说就是形成了
的一个子串。这种情况下,直接删除
以及
的操作次数是
,并且已经合法。如果交换仍然具有意义,那么要求:
亦即。换言之,只有在
时,对
和
进行的交换是可能存在意义的。因此,仅在这一极强的限制满足时,我们才进行转移:
综上,最终的转移方程为:
最后的答案为,总的时间复杂度为
。
后记
代码很简单。如果想看可以去https://github.com/cnzzx/AlgorithmCompetitions