问题描述
给你一个下标从 0 开始的二维数组 grid ,数组大小为 2 x n ,其中 grid[r][c] 表示矩阵中 (r, c) 位置上的点数。现在有两个机器人正在矩阵上参与一场游戏。
两个机器人初始位置都是 (0, 0) ,目标位置是 (1, n-1) 。每个机器人只会 向右 ((r, c) 到 (r, c + 1)) 或 向下 ((r, c) 到 (r + 1, c)) 。
游戏开始,第一个 机器人从 (0, 0) 移动到 (1, n-1) ,并收集路径上单元格的全部点数。对于路径上所有单元格 (r, c) ,途经后 grid[r][c] 会重置为 0 。然后,第二个 机器人从 (0, 0) 移动到 (1, n-1) ,同样收集路径上单元的全部点数。注意,它们的路径可能会存在相交的部分。
第一个机器人想要打击竞争对手,使 第二个 机器人收集到的点数 最小化 。与此相对,第二个 机器人想要 最大化 自己收集到的点数。两个机器人都发挥出自己的最佳水平的前提下,返回第二个机器人收集到的点数 。
案例1:
输入:grid = [[1,3,5,15],[1,3,3,1]]
输出:7
解释:第一个机器人的最佳路径如红色所示,第二个机器人的最佳路径如蓝色所示。
第一个机器人访问过的单元格将会重置为 0 。
第二个机器人将会收集到 0 + 1 + 3 + 3 + 0 = 7 个点。
解决方案
通过题目可以知道,第一个机器人所走的路线,只能向下或者向右,那么就会出现两种情况,第一种情况:一直向右走到最后一格再向下到达目的地,第二种情况:向下走后一直向右走到目的地。所以最开始的思路便是,遍历第一个机器人在每一列拐弯所得的结果,同时,需要解题人思考的是,第一个机器人并不需要找到最大值,第一个机器人所走的结果为了让第二个机器人得到的结果最小,所以这里并不能DP,通过图片可以观察到,第二个机器人所得结果有两种情况:选择第一机器人拐点右侧结果,选择第一机器人拐点左侧结果。综合思路得到的代码如下:
#遍历上下两列的结果(第二机器人的最终结果) previous_list= [0] last_list = [0] Num = len(grid[0]) #记录一列的步数 for i in range(Num): previous_list.append(previous_list[-1] + grid[1][i]) for i in range(Num- 1, -1, -1): last_list.append(last_list[-1] + grid[0][i]) last_list.reverse() #反向输出列表 (记录右侧剩余) ans = float('inf') #给予一个无穷变量 for i in range(Num): # 左侧剩余分数 left_ans = previous_list[i] # 右侧剩余分数 right_ans = last_list[i+1] ans = min(ans, max(left_ans, right_ans)) #从中得到最后的答案 print(ans) |
结语
此题主要解题思路便是前缀和,解决问题需要多思考,此题最开始想的是DP但是仔细看题,思考过后便会找到问题所求