0%

CF2133D Chicken Jockey

题意简述

Steve 做了一个愚蠢的决定:他在夜晚去挖矿,结果遇到了一种可怕的生物:鸡骑士!

一个鸡骑士由 $n$ 个生物依次叠在一起组成,其中第 $1$ 个生物在最底部,第 $n$ 个生物在最顶部。第 $i$ 个生物的初始生命值为 $h_i$。

在一次攻击中,Steve 可以对任意一个生物造成 $1$ 点伤害。如果某个生物的生命值降到 $0$ 或更低,它就会死亡,它上方的所有生物会掉落并重新形成一个新的堆叠。在新的堆叠中,底部的生物会因为掉落受到伤害:它会受到等于其在原堆叠中下方生物数量的掉落伤害(即之前在它下方的生物个数,包括刚刚死亡的那个)。这一伤害可能会杀死它,此时它上方的生物会再次掉落并重新形成堆叠,如此反复。

Steve 的剑耐久度很低,因此他想知道杀死所有生物所需的最少攻击次数。

思路分析

题意的摔落伤害其实就是根据当前高度决定的。

那么摔落伤害其实可以分为两种:$1$ 和非 $1$。

摔落伤害为 $1$ 其实意思就是当前位于下面第二个,杀掉最下面生物后自然掉落造成的伤害。

而摔落伤害非 $1$ 的意思是指从中间杀掉一个后,剩下的掉下来受的伤害。那么就要在最开始的序列里面开杀才能保证摔落伤害最大。

两种情况分别考虑。先记 $dp _ i$ 表示杀掉前 $i$ 个生物需要的最小攻击次数。

如果按顺序杀,那么就要从前一个状态转移过来然后用 $hi-1$ 次攻击(有 $1$ 的摔落伤害)杀掉第 $i$ 个生物,即 $dp_i=dp{i-1}+(h_{i}-1)$;

如果这个要最大化摔落伤害,那么就要把上一个生物在最开始杀掉,花费 $h{i-1}$ 次攻击,造成 $i-1$ 的摔落伤害,然后补刀。但是这种情况是从两个生物前的状态转移过来,即 $dp_i=dp{i-2}+h_{i-1}+\max(0, h_i-(i-1))$。

两种情况取最小值。

反思

一直在钻“从高往低杀一定不劣”的牛角尖。

逆序 dp 的问题就是不好建立转移方程,因为需要用到之后的状态。

但实际上消耗的攻击次数反而是跟前面的值息息相关。

如果优先选择击杀,那么会减少后续的摔落伤害;如果优先选择让其摔落,则需要考虑摔落后对不同位置的影响,转移本质上依然是由前向后建立。

当转移方向不确定时,可以尝试将状态定义与消耗量(或前缀性质)挂钩,避免依赖未来状态。

这题 1900 分。