486. Predict the Winner
题目理解:
有两个玩家, 每个玩家每次可以选择数组头或为的数作为得分, 交替进行, 玩家1先选. 假如两个玩家都以最优策略进行游戏, 对于给出的数组, 判断玩家1是否能取胜.
思路:
用 f[i][j][p]
记录得分, 表示对于数组[i, j]段先手取p的最大得分(p=0, 头, p=1, 尾);
所以问题的答案就是 f[0][n-1]
的两个值是否大于对应后手两个值的真假关系
要写出 f[0][n-1]
状态转移方程要考虑的问题: 假如先取数组头, 那么就要求 f[0][n-1][0]
, 这时候剩下 [1, n-1], 因为玩家总是进行最优取法, 所以后取的会选 f[1][n-1][0]
和 f[1][n-1][1]
中较大值, 根据这个选择, f[0][n-1][0]
只能取到剩下的部分, [2, n-1] 或 [1, n-2]; f[0][n-1][1]
也是如此, 这样就能够写出状态转移方程了.
1 | f[x][y][0] = nums[x] + (f[x+1][y][0]>f[x+1][y][1]?max(f[x+2][y][0], f[x+2][y][1]):max(f[x+1][y-1][0], f[x+1][y-1][1])); |
实现的时候用了递归的方法, 编程难度较低; 初始状态需要算每个 f[i][i][0] f[i][i][1]
;
小结:
这道题还有其他更好的做法, 给个方向, 对于[i, j], 一个人若是取了 g[i][j]
, 那么另一个人的得分肯定是 Total[i][j] - g[i][j]
, 状态转移: g[i][j] = max{ n(i) + Total[i+1][j] - g[i+1][j], n(j) + Total[i][j-1] - g[i][j-1] }
Submission Detail:
code:
1 |
|