LCP 57-打地鼠
欢迎各位勇者来到力扣城,本次试炼主题为「打地鼠」。
{:height=”200px”}
勇者面前有一个大小为 3*3 的打地鼠游戏机,地鼠将随机出现在各个位置,moles[i] = [t,x,y] 表示在第 t 秒会有地鼠出现在(x,y) 位置上,并于第 t+1 秒该地鼠消失。 勇者有一把可敲打地鼠的锤子,初始时刻(即第 0 秒)锤子位于正中间的格子(1,1),锤子的使用规则如下: - 锤子每经过 1 秒可以往上、下、左、右中的一个方向移动一格,也可以不移动 -
锤子只可敲击所在格子的地鼠,敲击不耗时 请返回勇者最多能够敲击多少只地鼠。 注意: -
输入用例保证在相同时间相同位置最多仅有一只地鼠 示例 1: >输入: moles = [[1,1,0],[2,0,1],[4,2,2]] >
输出:
2> >解释: >第 0 秒,锤子位于 (1,1) >第 1 秒,锤子移动至 (1,0) 并敲击地鼠 >第 2 秒,锤子移动至 (2,0)
第 3 秒,锤子移动至 (2,1) >第 4 秒,锤子移动至 (2,2) 并敲击地鼠 >因此勇者最多可敲击 2 只地鼠 示例 2:
输入:moles = [[2,0,2],[5,2,0],[4,1,0],[1,2,1],[3,0,2]]> >输出:3> >解释: >第 0
秒,锤子位于 (1,1) >第 1 秒,锤子移动至 (2,1) 并敲击地鼠 >第 2 秒,锤子移动至 (1,1) >第 3 秒,锤子移动至 (1,0) >第
4 秒,锤子在 (1,0) 不移动并敲击地鼠 >第 5 秒,锤子移动至 (2,0) 并敲击地鼠 >因此勇者最多可敲击 3 只地鼠 示例 3:
输入:moles = [[0,1,0],[0,0,1]]> >输出:0> >解释: >第 0 秒,锤子初始位于 (1,1),此时并不能敲击
(1,0)、(0,1) 位置处的地鼠 提示: +1 <= moles.length <= 10^5+moles[i].length == 3+0 <= moles[i][0] <= 10^9+0 <= moles[i][1], moles[i][2] < 3
解法:DP
假设没有时间 0 出现的地鼠,记 f_i 表示考虑前 i 只地鼠,刚刚打完了第 i 只,最多能打中几只。转移即是枚举上一只打中的地鼠 j,那么从打中地鼠 j 到打中地鼠 i 经过的时间为 t = (t_i - t_j),锤子需要移动的距离为 d = |x_i - x_j| + |y_i - y_j|。如果 t \ge d 就可以打完 j 再打 i。
朴素枚举 j 的复杂度是 \mathcal{O}(n^2) 的。由于棋盘是 3 \times 3 的,因此 d 最大值是 4,那么遇到 t > 4 的情况就直接用前缀 max 更新答案即可。由于每个时间每个位置最多一只地鼠,那么无法用前缀和更新的 j 与 i 的差距最大只有 4 \times 3 \times 3 = 36,这样就把复杂度降到了 \mathcal{O}(n)。
参考代码(c++)
1 | class Solution { |