题目
【题目描述】
林老师是一位大理石收藏家,他在家里收藏了$N$块各种颜色的大理石,第$i$块大理石的颜色为$a_i$。
但是林老师觉得这些石头在家里随意摆放太过凌乱,他希望把所有颜色相同的石头放在一起。
换句话说,林老师需要对现有的大理石重新进行排列,在重新排列之后,对于每一个颜色$j$,如果最左边的颜色为$j$的大理石是第$l$块大理石,最右边的颜色为$j$的大理石是第$r$块大理石,那么从第$l$块大理石到第$r$块大理石,这些石头的颜色都为$j$。
由于这些大理石都比较重,林老师无法承受这些大理石的重量太久,所以他每次搬运只能交换相邻的两块大理石。
请问,林老师最少需要进行多少次搬运?
【输入格式】
第一行输入一个数字$N(2≤N≤4*10^5)$,表示大理石的总数。
第二行输入$N$个数字$a_1,a_2…,an(1≤a_i≤20)$表示第$i$块大理石的颜色为$a_i$。
【输出格式】
输出林老师最少需要搬运的次数。
【样例输入】
样例输入 1 7 3 4 2 3 4 2 2 样例输入 2 5 20 1 14 10 2 样例输入 3 13 5 5 4 4 3 5 7 6 5 4 4 6
【样例输出】
样例输出 1 3 样例输出 2 0 样例输出 3 21
【解题经历】
刚拿到这道题,我就被它的时间限制深深地吸引:$4000ms$?
那么长的时间限制肯定是暴搜穷竭搜索算法啊
于是推出了样例之后就开始码搜索...
打到后面发现自己连搜索都打不出来,于是这么一个伟大的算法就半路夭折了...
【正解&代码】
一道几乎可以说是模板的状压DP题。
观察所有的数据范围,发现$1≤a_i≤20$,而几乎是极端的对立,$2≤N≤4*10^5$,可以说对于$a_i$来说$N$是十分大了。
而时间限制又十分巨大:$4000ms$。
那么这又说明什么了吗?
在输入的数据中,若其中一两个的范围十分小,而其他数据又大得不正常
并且时间限制又异常宽松
对于时间来说,这道题的常数非常大(或者是某些模拟题)
对于空间来说,若用其他的空间来开数组是无法承受的
则说明这道题是状压DP,而且压缩的对象就是针对这些比较小的数的
那么,这道题的状态?
定义$dp$一维数组,其中对于$dp_i$,将$i$转换成二进制之后,对于其某一位,若这一位为一,说明这个状态中,第$i$种颜色已经全部被放在一起了
再定义$c$二维数组,其中$c_{ij}$表示在初始状态中,所有第$j$种颜色的石头前的第$i$种颜色的石头的个数
那么就有状转方程$$dp_i=dp_{i-(1< 那么问题又来了,这个$cost(j)$怎么算呢? 首先我们把问题转化一下,每种石头可以往左或者往右交换 那么我们可以理解为这个石头$i$可以选择往右交换(与石头$i+1$交换),或者是它的前一个石头往右交换(石头$i-1$与石头$i$交换) 那么现在的交换规则就变成全部往右交换 现在我们来看一看状态。假设我们现在有这样一个状态(二进制): 位数:$7654321$(倒着排) 状态:$1000110$ 那么这个状态的意思就是在这个状态下,第$2,3,7$种颜色都已经排在一起了 那么这个状态是从哪种状态来的呢? 当然,是从状态$1000100,1000010,0000110$转移来的 那么这三个状态有什么区别呢?他们还原的石头颜色的顺序不同,而这就导致他们的花费不同。 那么我们可以这样总结: 对于一个状态,假设我们已经枚举到第$i$种颜色,而现在我们要还原第$j$种颜色 如果这个颜色$i$已经被还原过了,说明它的$cost$是已经被前面所计算过的,那么我们就不需要计算它的$cost$了 如果它没有被还原,那么加上第$j$种颜色的石头一共需要和它交换的次数 口胡还是太难了代码见下 1 #include