🔗 题目链接
题目描述
给你一个整数数组 nums 。玩家 1 和玩家 2 基于这个数组设计了一个游戏。
玩家 1 和玩家 2 轮流进行自己的回合,玩家 1 先手。开始时,两个玩家的初始分值都是 0 。每一回合,玩家从数组的任意一端取一个数字(即,nums[0] 或 nums[nums.length - 1]),取到的数字将会从数组中移除(数组长度减 1 )。玩家选中的数字将会加到他的得分上。当数组中没有剩余数字可取时,游戏结束。
如果玩家 1 能成为赢家,返回 true 。如果两个玩家得分相等,同样认为玩家 1 是游戏的赢家,也返回 true 。你可以假设每个玩家的玩法都会使他的分数最大化。
题目分析
题目有一句”你可以假设每个玩家的玩法都会使他的分数最大化“很关键,说明两个人都是绝对聪明的人,他们的想法都是一样的。
这道题我们发现数组 nums 是不断变化的,所以可以用动态规划的思路来做。
dp[i][j]表示的在[i, j]所组成的子数组,先手玩家比后手玩家多得的分数(正数则为多得,负数则为少得),动态规划方程可以表示为:

在[i, j] 数组中,玩家 1 作为先手,有两种选择:
- 选择
nums[i],那么剩下的[i+1, j]则由玩家 2 作为先手来选择- 在
[i+1, j]中,玩家 2 作为先手会比玩家 1 多得的分数是dp[i+1][j]
- 在
- 选择
nums[j],那么剩下的[i, j-1]则由玩家 2 作为先手来选择- 在
[i, j-1]中,玩家 2 作为先手会比玩家 1 多得的分数是dp[i][j-1]
- 在

我们假设nums数组为[1, 5, 8, 3, 5, 2],则表示为:
| nums | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| 值 | 1 | 5 | 8 | 3 | 5 | 2 |
那么,我们可以得到一个 6×6 的二维表格,只需要把表格上半部分填充完整即可。
| dp[i][j] | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| 0 | 1 | ❓ | ❓ | ❓ | ❓ | ❓ |
| 1 | - | 5 | ❓ | ❓ | ❓ | ❓ |
| 2 | - | - | 8 | ❓ | ❓ | ❓ |
| 3 | - | - | - | 3 | ❓ | ❓ |
| 4 | - | - | - | - | 5 | ❓ |
| 5 | - | - | - | - | - | 2 |
首先,我们填充j=1列,很容易发现,dp[0][1]的结果是 4。
| dp[i][j] | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| 0 | 1 | 4 | ❓ | ❓ | ❓ | ❓ |
| 1 | 5 | ❓ | ❓ | ❓ | ❓ | |
| 2 | 8 | ❓ | ❓ | ❓ | ||
| 3 | 3 | ❓ | ❓ | |||
| 4 | 5 | ❓ | ||||
| 5 | 2 |
接下来,我们填充j=2列:
| dp[i][j] | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| 0 | 1 | 4 | 4 | 1 | ❓ | ❓ |
| 1 | 5 | 3 | 0 | ❓ | ❓ | |
| 2 | 8 | 5 | ❓ | ❓ | ||
| 3 | 3 | ❓ | ❓ | |||
| 4 | 5 | ❓ | ||||
| 5 | 2 |
接下来,我们填充j=3列:
| dp[i][j] | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| 0 | 1 | 4 | 4 | 1 | ❓ | ❓ |
| 1 | 5 | 3 | 0 | ❓ | ❓ | |
| 2 | 8 | 5 | ❓ | ❓ | ||
| 3 | 3 | ❓ | ❓ | |||
| 4 | 5 | ❓ | ||||
| 5 | 2 |
接下来,我们填充j=4列:
| dp[i][j] | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| 0 | 1 | 4 | 4 | 1 | 4 | ❓ |
| 1 | 5 | 3 | 0 | 5 | ❓ | |
| 2 | 8 | 5 | 6 | ❓ | ||
| 3 | 3 | 2 | ❓ | |||
| 4 | 5 | ❓ | ||||
| 5 | 2 |
最后,,我们填充j=5列:
| dp[i][j] | 0 | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|---|
| 0 | 1 | 4 | 4 | 1 | 4 | 4 |
| 1 | 5 | 3 | 0 | 5 | -3 | |
| 2 | 8 | 5 | 6 | 8 | ||
| 3 | 3 | 2 | 0 | |||
| 4 | 5 | 3 | ||||
| 5 | 2 |
最后,我们发现,玩家 1 是胜利的。
题解代码
/**
* @param {number[]} nums
* @return {boolean}
*/
var PredictTheWinner = function (nums) {
const len = nums.length;
const dp = new Array(len);
for (let i = 0; i < len; i++) {
dp[i] = new Array(len);
dp[i][i] = nums[i];
}
for (let j = 1; j < len; j++) {
for (let i = j - 1; i >= 0; i--) {
dp[i][j] = Math.max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1]);
}
}
return dp[0][len - 1] >= 0;
};
运行结果














![[附源码]Node.js计算机毕业设计高校科研项目申报管理信息系统Express](https://img-blog.csdnimg.cn/857d02700cf047e5b71f8026565e0ead.png)




