欢迎光临散文网 会员登陆 & 注册

[Codeforces is All You Need] ER 145 D (1809D) - Solution

2023-03-24 12:01 作者:故寓诸无竟  | 我要投稿

题目简述

        给定长度为n0%2F1串,每次操作可以删除任意元素(代价为w_d%20%3D%2010%5E%7B12%7D%2B1)或交换相邻元素的位置(代价为w_s%20%3D%2010%5E%7B12%7D)。求将该串变为非递减串的最少的代价(空串也是非递减的)。

        原题目链接:https://codeforces.com/contest/1809/problem/D

思路

        每次操作代价的数值是最扎眼的。%5Cmin%5C%7Bw_s%2Cw_d%5C%7D足够大并且%7Cw_d-w_s%7C足够小的奇怪数值,保证了:无论进行的操作种类如何,总操作次数越少越好。这是因为至多n-1次删除就一定能把串变成非递减的,而此时(n-1)%7Cw_d-w_s%7C%20%5Cll%20%5Cmin%5C%7Bw_s%2Cw_d%5C%7D(差异凑不够一次操作),因此操作次数在优化中占据了绝对的主导地位。

        另一个简单的事实是,非递增串的前缀必然也是非递增的。如此优良的性质,不令f(i)表示s_%7B1...i%7D变为以不以0结尾的非递增序列所需的最小代价,是很不划算的。(以0结尾则是平凡的,答案是cnt_1(i)%20%5Ccdot%20w_d,其中cnt_1(i)表示s_%7B1...i%7D1的数目。)

        首先f(0)%20%3D%200是平凡的边界。

        对于s_i%20%3D%201的情形,转移是非常容易的。我们可以不删除s_i,于是:

f(i)%20%3D%20%5Cmin%5C%7Bf(i-1)%2C%20cnt_1(i-1)%5Ccdot%20w_d%20%5C%7D

        其中后一项是将s_%7B1...i-1%7D全变为0的代价。另外,此时我们没有任何必要删除s_i

        对于s_i%20%3D%200的情形,我们必须要把它除掉。如果直接删除,有:

f(i-1)%20%2B%20w_d%20%5Cto%20f(i)

        如果使用交换,事情稍微复杂起来了,我们需要考虑一下交换操作在什么时候才是有意义的。假设cnt_1(i-1)%20%5Cge%202,且所有s_j%20%3D%201的下标序列依次序为%5C%7Bi_1%2C...%2Ci_K%5C%7D。如果对s_i%20%3D%200交换后进行了删除,那么需要的操作次数%5Cge%202,且与直接删除完全等价,因此这种行为是无意义的。这意味着如果要对s_i%20%3D%200进行交换,必须贯彻到底,只对其使用交换。在这种前提下,为使序列非递减,假设需要删除%5C%7Bi_1%2C...%2Ci_M%5C%7DM%3CK),那么仅仅由于s_i%20%3D%200带来的操作次数为:

M%20%2B%20(i-i_%7BM%2B1%7D)%20%5Cge%20K

        如果M%2B(i-i_%7BM%2B1%7D%20)%20%3E%20K,那么显然不如直接将K1全部删除。

        如果M%2B(i-i_%7BM%2B1%7D)%20%3D%20K,这意味着:

i_%7BM%2B1%7D%20%3D%20i_%7BM%2B2%7D-1%20%3D%20...%20%3D%20i_%7BK%7D-(K-M-1)%20%3D%20i-(K-M-2)

        用人话说就是i_%7BM%2B1%7D%2C...%2Ci_K%2Ci形成了s的一个子串。这种情况下,直接删除s_i%3D0以及%5C%7Bi_1%2C...%2Ci_M%5C%7D的操作次数是1,并且已经合法。如果交换仍然具有意义,那么要求:

M%2B1%20%5Cge%20M%2B(i-i_%7BM%2B1%7D)

        亦即i_%7BM%2B1%7D%20%5Cge%20i-1。换言之,只有在s_%7Bi-1%7D%20%3D%201时,对s_is_%7Bi-1%7D进行的交换是可能存在意义的。因此,仅在这一极强的限制满足时,我们才进行转移:

w_s%20%2B%20%5Bcnt_1(i-1)-1%5D%20%5Ccdot%20w_d%20%5Cto%20f(i)

        综上,最终的转移方程为:

f(i)%20%3D%20%5Cbegin%7Bcases%7D%0A0%20%26%2C%20i%3D0%20%5C%5C%0A%5Cmin%20%5C%7Bf(i-1)%2Ccnt_1(i)%5Ccdot%20w_d%5C%7D%20%26%2C%20i%5Cge%201%20%5Cwedge%20s_i%20%3D%201%20%5C%5C%0A%5Cmin%20%5C%7Bf(i-1)%2Bw_d%2C%20w_s%20%2B%20%5Bcnt_1(i-1)-1%5D%5Ccdot%20w_d%5C%7D%20%26%2C%20i%5Cge%202%20%5Cwedge%20s_i%20%3D%200%20%5Cwedge%20s_%7Bi-1%7D%3D1%20%5C%5C%0Af(i-1)%2Bw_d%20%26%2C%20else%0A%5Cend%7Bcases%7D

        最后的答案为%5Cmin%20%5C%7Bf(n)%2C%20cnt_1(n)%20%5Ccdot%20w_d%5C%7D,总的时间复杂度为%5CTheta(n)

后记

        代码很简单。如果想看可以去https://github.com/cnzzx/AlgorithmCompetitions

[Codeforces is All You Need] ER 145 D (1809D) - Solution的评论 (共 条)

分享到微博请遵守国家法律