题解:P11400 [Code+#8 初赛] 打怪游戏

· · 题解

@yuruilin2026 和@Hootime 两个大佬认为这是道水题,一眼秒了,于是让我这个蒟蒻来做。
然后我直接输出 FALL,成功获得了 29 pts。

不可以,总司令。

让我们回到正题,我使用的是动态规划实现,时间复杂度为 O(3^q\times 2^n\times n\times k),这个时间复杂度看似很高,实际一点也不少,但是我们可以通过剪枝实现。

表示

转移

然后就开始推动态转移方程式,我们需要分两种情况:

  1. 使用这个道具;
  2. 不使用这个道具。

状态转移的核心思想是:从当前状态 s 出发,访问一个新的城市 i,并更新状态 s 和对应的 f[s]g[s]

1. 状态转移

假设当前状态为 s,尝试访问一个新的城市 i

2. 使用道具的状态转移

如果城市 i 有道具 d[i],则可以使用道具来减少怪物 i 的血量。假设当前状态为 s,尝试访问一个新的城市 i 并使用道具 d[i]

总结

  1. 不使用道具

    f[s] & g[s] + a[i] \leq b[f[s]] \\ f[s] + 1 & \text{其它} \end{cases} g[s] + a[i] & g[s] + a[i] \leq b[f[s]] \\ a[i] & \text{其它} \end{cases}
  2. 使用道具

    f[s \cup \{i\}] = \begin{cases} f[s] & g[s] + \max(a[i] - d[i], 0) \leq b[f[s]] \\ f[s] + 1 & \text{其它} \end{cases} g[s \cup \{i\}] = \begin{cases} g[s] + \max(a[i] - d[i], 0) & g[s] + \max(a[i] - d[i], 0) \leq b[f[s]] \\ \max(a[i] - d[i], 0) & \text{其它} \end{cases}

答案

我们需要找到所有城市都被访问过的状态,即 s = (1 << n) - 1,并检查 f[s] 是否小于 k。如果 f[s] < k,则输出 f[s] + 1b[f[s]] - g[s];否则输出 FAIL