1510. Stone Game IV
Description
Alice and Bob take turns playing a game, with Alice starting first.
Initially, there are n stones in a pile. On each player's turn, that player makes a move consisting of removing any non-zero square number of stones in the pile.
Also, if a player cannot make a move, he/she loses the game.
Given a positive integer n, return true if and only if Alice wins the game otherwise return false, assuming both players play optimally.
Example 1:
Input: n = 1 Output: true Explanation: Alice can remove 1 stone winning the game because Bob doesn't have any moves.
Example 2:
Input: n = 2 Output: false Explanation: Alice can only remove 1 stone, after that Bob removes the last one winning the game (2 -> 1 -> 0).
Example 3:
Input: n = 4 Output: true Explanation: n is already a perfect square, Alice can win with one move, removing 4 stones (4 -> 0).
Constraints:
1 <= n <= 105
Solutions
Solution 1: Memoization
Thinking
Players alternately remove a square number of stones from a pile of \(n\); the one who takes the last stone wins. \(n\le 10^5\), so expanding the full game tree would recompute the same remainder many times.
A position depends only on the remaining count: it is winning if some move leaves the opponent in a losing position. Memoized \(dfs(i)\) answers whether the player to move wins with \(i\) stones, trying every \(j^2\le i\). Each state has \(O(\sqrt{i})\) transitions.
We design a function \(dfs(i)\), which represents whether the current player can win the game when there are \(i\) stones in the pile. If the current player can win, it returns \(true\); otherwise, it returns \(false\). The answer is \(dfs(n)\).
The calculation process of the function \(dfs(i)\) is as follows:
- If \(i \leq 0\), it means the current player cannot make any move, so the current player loses the game, return \(false\);
- Otherwise, enumerate the number of stones \(j\) that the current player can take away, where \(j\) is a square number. If the other player cannot win the game after the current player takes away \(j\) stones, then the current player wins the game, return \(true\). If all \(j\) enumerated cannot satisfy the above condition, then the current player loses the game, return \(false\).
To avoid repeated calculations, we can use memoization, i.e., use an array \(f\) to record the calculation results of the function \(dfs(i)\).
The time complexity is \(O(n \times \sqrt{n})\), and the space complexity is \(O(n)\). Where \(n\) is the number of stones in the pile.
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
Solution 2: Dynamic Programming
Thinking
Memoization still pays recursion and cache overhead, while the asymptotic cost matches a bottom-up table. Let \(f[i]\) be whether \(i\) stones is a win, and fill \(i\) in increasing order. A single square that lands on a losing successor makes \(f[i]\) true. The implementation is a loop and needs no call stack.
We can also use dynamic programming to solve this problem.
Define an array \(f\), where \(f[i]\) represents whether the current player can win the game when there are \(i\) stones in the pile. If the current player can win, then \(f[i]\) is \(true\), otherwise it is \(false\). The answer is \(f[n]\).
We enumerate \(i\) in the range \([1,..n]\), and enumerate \(j\) in the range \([1,..i]\), where \(j\) is a square number. If the other player cannot win the game after the current player takes away \(j\) stones, then the current player wins the game, i.e., \(f[i] = true\). If all \(j\) enumerated cannot satisfy the above condition, then the current player loses the game, i.e., \(f[i] = false\). Therefore, we can get the state transition equation:
Finally, we return \(f[n]\).
The time complexity is \(O(n \times \sqrt{n})\), and the space complexity is \(O(n)\). Where \(n\) is the number of stones in the pile.
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |