CF1415F - Cakes for Clones 题解

dyls nb 嗷,切 2900 的题!虽然我也没看题解(咋又装起来了)

然后我的复杂度好像比 dyls 优


把这题 A 掉的时候是假的热泪盈眶……周天搞了一下午这个题到最后都没调出来,今天竟然一下子就把错误找出来了,感动中国(

交了 22 次,有提交记录为证,虽然远抵不上 455D 这个交了 50 次的(


下面扯正题

我们考虑按照时间顺序,每个蛋糕是被本人还是被分身收集了,这样一个 01 序列。考虑对一个 particular 的 01 序列考虑是否能够实现。

我们考虑以时间为横轴,位置为纵轴建直角坐标系,然后就可以画出这个人的行动轨迹。那么这个 01 序列的限制是分 0 和 1:被本人收集那就是行动轨迹必须经过这个点;被分身收集的话,那就是对于每个这样的蛋糕,行动轨迹必须穿过 \(y=\) 当前蛋糕位置,并且左端是上一个蛋糕的时间,右端是这个蛋糕的时间,这样一条水平线。注意到本人收集的蛋糕能一定程度上的确定行动轨迹,比较稳定,于是我们以它为阶段考虑。

那么两个相邻的被本人收集蛋糕之间会是什么样的呢。假设至少存在一个分身收集的蛋糕,没有的话后面另说。那么显然最左边后面的都一定是在本阶段内被穿过;而最左边的那个所对应的水平线一定穿过了左端点所在竖直线,也就是说它可能先于或后于左端点被收集。同理,右端点后面第一个也可能先于右端点被收集。这样一来我们可以很自然的想出一个 DP 状态:\(dp_{i,0/1}\) 表示考虑到蛋糕 \(i\)\(i\) 被本人收集,然后 \(i+1\) 是否被分身收集且在本阶段内被收集,这种状态是否能做到。

转移的话就直接枚举本阶段左端点 \(j\)。然后显然需要从 \(j\to i\),我们可以预处理出从 \(j\) 开始出发到某个地方一连串都是被分身收集,的最小到达时间(贪心就可以了,注意每次需要和水平线左端点取 \(\max\))。因为 \(j\) 对应状态可能是 \(0/1\),所以预处理的时候需要分开考虑是否需要经过 \(j+1\)。然后也需要根据 \(i\) 对应 \(0/1\) 判断是否需要经过 \(i+1\)。这时候注意也要和水平线左端点取 \(\max\),这就是导致我调这么长时间的原因。

但这样考虑还不完备,前面遗留了一个问题:本阶段内可能不存在被分身收集的点。这种情况稍微有点麻烦。那么就会出现这种现象:\(i+1\) 的水平线会贯穿好几条竖直线,那么前面那些竖直线所对应的右边的被分身收集的点就不再是 \(+1\) 了,而要再往后集中到 \(i+1\)

不过还是可做的。几经尝试,发现可以枚举 \(i+1\) 是在哪两个相邻蛋糕 \(j,j+1\) 之间被收集的。又分为两类:

  1. 两个蛋糕都是被本人收集。这种情况较简单,因为只能是 \(dp_{j,0}\)\(j+1\) 本来就不是分身收集的。然后需要 \(j\to i+1\to j+1\to i\)\(j+1\to i\) 可以区间 DP 预处理;
  2. \(j\) 是分身收集,\(j+1\) 是本人收集。我们考虑再枚举往左数第一个本人收集的位置 \(k\),那么 \(k\to j\) 之间按照之前说的 DP 转移方式考虑,对后面列式计算是否可以到 \(j+1\) 的贡献是一个关于 \(k,j\) 的初始时间 DP 值。然后就判 \(j\to i+1\to j+1\to i\),老样子。这样子是三方的,然后注意到 \(k\) 唯一产生的贡献就是一个只关于 \(k,j\) 的东西,于是可以对 \(j\) 前缀预处理一下,就变成平方了。

虽然也要分挺多类,但是代码只有 2.5k,不像 dy 有 6k()。而且这样一个 2900 题,和上面那个 2600 题比起来,已经很幸福了(

code

posted @ 2020-12-22 22:45  ycx060617  阅读(96)  评论(0编辑  收藏  举报