zoukankan      html  css  js  c++  java
  • CF1415F

    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 o 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 o i+1 o j+1 o i)(j+1 o i) 可以区间 DP 预处理;
    2. (j) 是分身收集,(j+1) 是本人收集。我们考虑再枚举往左数第一个本人收集的位置 (k),那么 (k o j) 之间按照之前说的 DP 转移方式考虑,对后面列式计算是否可以到 (j+1) 的贡献是一个关于 (k,j) 的初始时间 DP 值。然后就判 (j o i+1 o j+1 o i),老样子。这样子是三方的,然后注意到 (k) 唯一产生的贡献就是一个只关于 (k,j) 的东西,于是可以对 (j) 前缀预处理一下,就变成平方了。

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

    code

  • 相关阅读:
    怎样从server获取图片
    面经
    cordova百度导航插件使用
    swift初探(供objective c开发人员參考)
    右击菜单简单实现
    ios--计时器演示样例:一闪一闪亮晶晶(动画)
    新建cocos2d-xproject
    atititt.java定时任务框架选型Spring Quartz 注解总结
    UIViewController的生命周期及iOS程序运行顺序
    hdu 1162 Eddy's picture (Kruskal算法,prim算法,最小生成树)
  • 原文地址:https://www.cnblogs.com/ycx-akioi/p/solution-cf1415f.html
Copyright © 2011-2022 走看看