1 条题解

  • 0
    @ 2026-4-21 18:16:57

    转载:

    解题思路:

    题目中强调的是移动,不能往里面添加,也不能从树中拿走。这个移动操作就给我们造成了一些困难,起初想一些 dp 的方法,感觉都不是很靠谱。

    于是看了官方题解,题解中用了一步巧妙地转化,然后递归求解,很有借鉴意义。

    首先对于移动操作次数最少,我们可以转化成,往树里插入 SUM 个点,尽量把点放入本来有苹果的位置,最大覆盖多少个的问题。那么原来没有苹果,现在要放点,这些位置的个数就是答案。

    完成这一步转化之后就要挖掘题目性质,绝对值差 1 这个性质十分重要,因为这近似于一步二分,也就是如果我们从顶点开始递归地往下放,那么最多进行 log SUM 层就能使得剩下的可放点数达到 0 或 1,这就使我们得到一种很可行的分治求解的方法:Get(x, cnt) 表示向 x 这个点为根的子树中插入 cnt 个苹果,向空点放的情况最少有多少个(也就是移动次数最少有多少次)。对于 cnt 是偶数的情况,就直接 Get(x.left, cnt >> 1), Get(x.right, cnt >> 1), 而对于 cnt 是奇数,就要讨论一下左右放多放少这两种情况,取个 min 了。

    递归的终止条件:

    ① cnt == 0,返回0

    ② x == 0 && cnt > 0 返回INF(无解)

    ③ cnt == 1 子树中本来有苹果返回 1,无苹果返回 0

    P.S.题目中并没有给总点数,经过分析总点数不会超过叶结点的二倍。但是题目读入比较繁琐,字符串长度要开至少 5000。

    • 1

    信息

    ID
    699
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    0
    上传者