LeetCode486:预测赢家

题意

给定一个表示分数的非负整数数组。 玩家 1 从数组任意一端拿取一个分数,随后玩家 2 继续从剩余数组任意一端拿取分数,然后玩家 1 拿,…… 。每次一个玩家只能拿取一个分数,分数被拿取之后不再可取。直到没有剩余分数可取时游戏结束。最终获得分数总和最多的玩家获胜。

给定一个表示分数的数组,预测玩家1是否会成为赢家。你可以假设每个玩家的玩法都会使他的分数最大化。

Solution

很容易想到递归解决,但显然复杂度太大。所以我们采用记忆化搜索,把已经搜索过的状态记录下来,回溯过程中取最大值。

$dp[l][r]$ 表示在区间 $[l,r]$ 中,能赢过对方的最大分数。

状态转移:$dp[l][r] = max(nums[l] - dp[l + 1][r], nums[r] - dp[l][r - 1])$。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
static int[][] dp = new int[30][30];

public int dfs(int l, int r, int[] nums) {
if (dp[l][r] != 0)
return dp[l][r];
if (l == r) return dp[l][r] = nums[l];
return dp[l][r] = Math.max(nums[l] - dfs(l + 1, r, nums), nums[r] - dfs(l, r - 1, nums));
}

public boolean PredictTheWinner(int[] nums) {
int n = nums.length;
for (int i = 0; i < nums.length; i++) {
Arrays.fill(dp[i], 0);
}
return dfs(0, n - 1, nums) >= 0;
}
}
作者

Benboby

发布于

2020-09-01

更新于

2021-01-28

许可协议

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×