[BZOJ3523][Poi2014]KLO-Bricks——全网唯一 一篇O(n)题解+bzoj最优解

Description

有n种颜色的砖块,第i种颜色的砖块有a[i]个,你需要把他们放成一排,使得相邻两个砖块的颜色不相同,限定第一个砖块的颜色是start,最后一个砖块的颜色是end,请构造出一种合法的方案或判断无解。

HINT

【数据范围】

n,m≤1000000,1≤start,end≤n

∑ai<=1000000

Solution

全网唯一 一篇O(n)题解+bzoj最优解

这个题看大家都是优先队列,然后直接贪心放置。

还有用权值线段树来模拟堆过的%%%。

其实不用带logn也可以过的。

大家的方法是从左往右扫过去的。

对于这种插空排序的问题,还有一种考虑方法就是每个种类每个种类来考虑。

好处是,前面放过的种类放完了,和当前第i种永远不会产生冲突。

这就是我的大方向思路。

一、先不考虑端点固定的情况。

其实,不一定要先放最多的。

顺序可以随便。

假设放到完了前i种,那么,一共有sum[i]个。

对于后面的n-i种来说,前i种的方法对后面没有影响。

所以,肯定前i种放法中,选择相邻的情况最少的方案咯!

怎样凑出这个方案?

放完了前i种,设还剩下k个相邻位置。

1.对于第i种,肯定先插那k个位置中。这样每次相邻的-1,已经最优。

2.如果i种还剩下,那就从前面开始插空(不能和1中放的相邻)。这样相邻的数量不增不减。已经最优。

3.如果还剩下,那没有办法了。为了之后好处理,我们都把这些剩下的都放在末尾。

这样,不管你是数量较多的,还是数量较少的,

较多的,可以放在一起,由后面的再插空隔开。

较少的,就隔开之前相邻的。

至于怎么插空?

用一个最普通的链表就可以维护。

当然,我们每次要维护3中,开始连续的那一串的起始位置。方便下次直接访问。

二、有固定点呢?

两个端点比较麻烦。

所以我们就先放端点好了。

放的方法和上面差不多。

先放p,再放q

如果p的数量大于等于q。

那么放q的时候,直接插空,然后无论如何留下一个放末尾。

如果p的数量小于q。

那么放q的时候,插完空,直接往后放完即可。

(注意的是,这样的话有一个情况,就是在最后一个和倒数第二个之间还要插一个,后面放的时候特判一下)

然后放剩下k-2种。

按照刚才的策略即可。注意不能放在1前面,以及最后一个后面。

三、一些细节

1.可能有两个端点颜色相同的情况

猜你喜欢

转载自www.cnblogs.com/Miracevin/p/9885720.html