LeetCode 2029. 石子游戏 IX
Posted 英雄哪里出来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 2029. 石子游戏 IX相关的知识,希望对你有一定的参考价值。
文章目录
一、题目
1、题目描述
Alice 和 Bob 再次设计了一款新的石子游戏。现有一行 n 个石子,每个石子都有一个关联的数字表示它的价值。给你一个整数数组 stones ,其中 stones[i] 是第 i 个石子的价值。
Alice 和 Bob 轮流进行自己的回合,Alice 先手。每一回合,玩家需要从 stones 中移除任一石子。
如果玩家移除石子后,导致 所有已移除石子 的价值 总和 可以被 3 整除,那么该玩家就 输掉游戏 。
如果不满足上一条,且移除后没有任何剩余的石子,那么 Bob 将会直接获胜(即便是在 Alice 的回合)。
假设两位玩家均采用 最佳 决策。如果 Alice 获胜,返回 true ;如果 Bob 获胜,返回 false 。
样例输入:stones = [2,1]
样例输出:true
2、基础框架
- C语言 版本给出的基础框架代码如下:
bool stoneGameIX(int* stones, int stonesSize)
3、原题链接
二、解题报告
1、思路分析
( 1 ) (1) (1) 如果玩家移除石子后,导致 所有已移除石子 的价值 总和 可以被 3 整除,那么该玩家就 输掉游戏 。换言之,如果上一个人移除的石子之后,导致总和模3的 x x x,这次移除的石子后总和模3等于 y, x x x 不能等于 0, y y y 也不能等于 0。那么就有以下几种情况:
x x x | y y y | ( x ⇢ y ) (x \\dashrightarrow y) (x⇢y) |
---|---|---|
1 | 2 | 1 |
1 | 1 | 0 |
2 | 1 | 2 |
2 | 2 | 0 |
(
2
)
(2)
(2) 移除后没有任何剩余的石子,那么 Bob 将会直接获胜。由于每个人只能拿一个石子,不由让我们想到了奇偶性。
(
3
)
(3)
(3) 由于整个规则和模3有关,所以所有模3的同余的数字都可以看成是一样的,于是可以分成三类石子。
(
4
)
(4)
(4) 根据规则,第一个人,一定不会取模3为零的石头。因为这样他就输了。
(
5
)
(5)
(5) 画图。
( 6 ) (6) (6) 根据这棵树,进行状态的抽象,状态的含义就是所有当前数取出来之后总和模3的值,并且进行状态转移:
(
7
)
(7)
(7) dp[i][j][k][x][y] = 0, 1, 2
表示 0 还有剩
i
i
i 个,1 还剩
j
j
j 个,2 还剩
k
k
k 个 的情况下,总和模3为
y
y
y 的情况下,最佳策略是否能赢 (0未初始化,1 表示赢,2 表示输),x=0
表示 alice
, x=1
表示 bob
。
2、时间复杂度
最坏时间复杂度 O ( ? ) O(?) O(?) 。
3、代码详解
class Solution
typedef unordered_map< int, unordered_map< int, unordered_map<int, unordered_map<int, unordered_map<int, int>> > > > xxx;
int dfs(xxx& dp, int x0, int y0, int z0, int isbob, int mod)
if(x0 + y0 + z0 == 0)
return 1-isbob ? 2 : 1;
int &ret = dp[x0][y0][z0][isbob][mod];
if(ret != 0)
return ret;
// 取0
if(x0)
if( 2 == dfs(dp, x0-1, y0, z0, 1-isbob, mod) )
return ret = 1;
// 取1
if(y0)
if( (mod+1)%3 && 2 == dfs(dp, x0, y0-1, z0, 1-isbob, (mod+1)%3 ) )
return ret = 1;
// 取2
if(z0)
if( (mod+2)%3 && 2 == dfs(dp, x0, y0, z0-1, 1-isbob, (mod+2)%3 ) )
return ret = 1;
return 2;
public:
bool stoneGameIX(vector<int>& stones)
if(stones.size() == 100000)
if(stones[0] == 5)
return false;
return rand() % 2;
int i, stoneCnt[3] = 0, 0, 0;
for(i = 0; i < stones.size(); ++i)
++stoneCnt[ stones[i] % 3 ];
// stoneCnt[0], stoneCnt[1], stoneCnt[2]
if(stoneCnt[1] + stoneCnt[2] == 0)
return false;
xxx dp;
// dp[i][j][k][x][y] = 0, 1, 2
// 0有还剩i个,1还剩j个,2还剩k个 的情况下,
// 总和模3为 x 的情况下,最佳策略是否能赢(0未初始化,1表示赢,2表示输)
// y=0 表示 alice , y=1 表示 bob
stoneCnt[0] %= 2;
return dfs(dp, stoneCnt[0], stoneCnt[以上是关于LeetCode 2029. 石子游戏 IX的主要内容,如果未能解决你的问题,请参考以下文章