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).
Example 4:
Input: n = 7 Output: false Explanation: Alice can't win the game if Bob plays optimally. If Alice starts removing 4 stones, Bob will remove 1 stone then Alice should remove only 1 stone and finally Bob removes the last one (7 -> 3 -> 2 -> 1 -> 0). If Alice starts removing 1 stone, Bob will remove 4 stones then Alice only can remove 1 stone and finally Bob removes the last one (7 -> 6 -> 2 -> 1 -> 0).
Example 5:
Input: n = 17 Output: false Explanation: Alice can't win the game if Bob plays optimally.
Constraints:
1 <= n <= 10^5
石子游戏IV。
Alice 和 Bob 两个人轮流玩一个游戏,Alice 先手。
一开始,有 n 个石子堆在一起。每个人轮流操作,正在操作的玩家可以从石子堆里拿走 任意 非零 平方数 个石子。
如果石子堆里没有石子了,则无法操作的玩家输掉游戏。
给你正整数 n ,且已知两个人都采取最优策略。如果 Alice 会赢得比赛,那么返回 True ,否则返回 False 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/stone-game-iv
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题意不难理解,每轮游戏,每个玩家需要拿走一个非零的平方数。所以我们需要从1到N开始,对每一种情况的石子数量做判断,看他的DP值是true还是false。这里我们创建一个长度为N + 1的boolean数组,dp的含义是当数字为 i 的时候,到底是谁赢。这里我们定义dp[i] = true是Alice赢,反之则是Bob赢。
从1到N判断DP值,并且试着从N中拿出一个平方数,如果能使得剩下的数字的DP值为false,那么Alice就能赢。
时间O(n * 根号n)
空间O(n)
Java实现
1 class Solution { 2 public boolean winnerSquareGame(int n) { 3 boolean[] dp = new boolean[n + 1]; 4 for (int i = 1; i <= n; i++) { 5 for (int k = 1; k * k <= i; k++) { 6 if (!dp[i - k * k]) { 7 dp[i] = true; 8 break; 9 } 10 } 11 } 12 return dp[n]; 13 } 14 }