dfs + memo模版
private boolean canIWin(int n) {
boolean[] memo = new boolean[n + 1];
return dfs(n, memo);
}
private boolean dfs(int n, boolean[] memo) {
if (n < 0) {
return false;
}
if (memo[n] == true) {
return true;
}
boolean res = false;
for (int i = 1; i < 4; i++) {
if (n >= i) {
res = res | !dfs(n - i, memo);
}
}
return memo[n] = res;
}
1. Nim 游戏
class Solution {
public boolean canWinNim(int n) {
boolean memo[] = new boolean[Math.max(n + 1, 4)];
memo[1] = true;
memo[2] = true;
memo[3] = true;
for (int i = 4; i <= n; i++) {
memo[i] = !memo[i - 1] || !memo[i - 2] || !memo[i - 3];
}
return memo[n];
}
}
2. 预测赢家
class Solution {
public boolean PredictTheWinner(int[] nums) {
int[][] memo = new int[nums.length][nums.length];
return dfs(nums, 0, nums.length - 1, memo) >= 0;
}
private int dfs(int[] nums, int i, int j, int[][] memo) {
if (i > j) {
return 0;
}
if(memo[i][j]!=0){
return memo[i][j];
}
memo[i][j] = Math.max(nums[i] - dfs(nums, i + 1, j, memo), nums[j] - dfs(nums, i, j - 1, memo));
return memo[i][j];
}
public boolean PredictTheWinner(int[] nums) {
int n = nums.length;
int[][] dp = new int[n][n];
for (int i = 0; i < n; i++) {
dp[i][i] = nums[i];
}
for (int len = 1; len < n; len++) {
for (int i = 0; i < n - len; i++) {
int j = i + len;
dp[i][j] = Math.max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1]);
}
}
return dp[0][n - 1] >= 0;
}
}
3. 除数博弈
class Solution {
public boolean divisorGame(int n) {
boolean[] memo = new boolean[n + 1];
return dfs(n, memo);
}
private boolean dfs(int n, boolean[] memo) {
if (n < 2) {
return false;
}
if (memo[n] == true) {
return true;
}
boolean res = false;
for (int i = 1; i <= n / 2; i++) {
if (n % i == 0 && !dfs(n - i, memo)) {
res = true;
break;
}
}
return memo[n] = res;
}
public boolean divisorGame(int n) {
return n%2==0;
}
}
4. 石子游戏
class Solution {
public boolean stoneGame(int[] piles) {
int n = piles.length;
int[][] memo = new int[n][n];
return dfs(piles, 0, n - 1, memo) > 0;
}
private int dfs(int[] piles, int i, int j, int[][] memo) {
if (i > j) {
return 0;
}
if (memo[i][j] != 0) {
return memo[i][j];
}
memo[i][j] = Math.max(piles[i] - dfs(piles, i + 1, j, memo), piles[j] - dfs(piles, i, j - 1, memo));
return memo[i][j];
}
public boolean stoneGame(int[] piles) {
int n = piles.length;
int[][] dp = new int[n][n];
for (int i = 1; i < n; i++) {
dp[i][i] = piles[i];
}
for (int len = 1; len < n; len++) {
for (int i = 0; i < n - len; i++) {
int j = i + len;
dp[i][j] = Math.max(piles[i]-dp[i+1][j] , piles[j]-dp[i][j-1]);
}
}
return dp[0][n - 1] > 0;
}
}
5. 石子游戏 II
class Solution {
public int stoneGameII(int[] piles) {
int n = piles.length;
int[] sum = new int[n];
for (int i = n - 1; i >= 0; i--) {
if (i == n - 1) {
sum[i] = piles[n - 1];
} else {
sum[i] = sum[i + 1] + piles[i];
}
}
int[][] memo = new int[n][n * 2];
return dfs(piles, 0, 1, memo, sum);
}
private int dfs(int[] piles, int index, int M, int[][] memo, int[] sum) {
if (index == piles.length) {
return 0;
}
if (piles.length - index <= 2 * M) {
return sum[index];
}
if(memo[index][M] != 0){
return memo[index][M];
}
int min = Integer.MAX_VALUE;
for (int i = 1; i <= 2 * M; i++) {
min = Math.min(min, dfs(piles, index + i, Math.max(M, i), memo, sum));
}
return memo[index][M] = sum[index] - min;
}
}
6. 石子游戏 III
class Solution {
public String stoneGameIII(int[] stoneValue) {
int n = stoneValue.length;
int[] memo = new int[n + 1];
int res = dfs(stoneValue, 0, memo);
if (res > 0) {
return "Alice";
} else if (res == 0) {
return "Tie";
} else {
return "Bob";
}
}
private int dfs(int[] stoneValue, int index, int[] memo) {
if (index == stoneValue.length) {
return 0;
}
if (memo[index] != 0) {
return memo[index];
}
int res = Integer.MIN_VALUE;
int sum = 0;
for (int i = index; i < index + 3 && i<stoneValue.length; i++) {
sum += stoneValue[i];
res = Math.max(res, sum - dfs(stoneValue, i + 1, memo));
}
return memo[index] = res;
}
}
7. 石子游戏 IV
class Solution {
public boolean winnerSquareGame(int n) {
boolean[] memo = new boolean[n + 1];
return dfs(n, memo);
}
boolean dfs(int n, boolean[] memo) {
if (n == 0) {
return false;
}
if (memo[n] == true) {
return true;
}
boolean res = false;
for (int i = 1; i *i<=n; i++) {
res |= !dfs(n - i * i, memo);
}
return memo[n] = res;
}
}
8. 石子游戏 V
class Solution {
public int stoneGameV(int[] stoneValue) {
int n = stoneValue.length;
int[][] memo = new int[n][n];
int[] sum = new int[n + 1];
for (int i = n - 1; i >= 0; i--) {
if (i == n - 1) {
sum[i] = stoneValue[i];
} else {
sum[i] = sum[i + 1] + stoneValue[i];
}
}
return dfs(memo, 0, n - 1, sum);
}
private int dfs(int[][] memo, int i, int j, int[] sum) {
if (i >= j) {
return 0;
}
if (memo[i][j] != 0) {
return memo[i][j];
}
int max = Integer.MIN_VALUE;
for (int k = i; k < j; k++) {
if (sum[i] - sum[k + 1] > sum[k + 1] - sum[j + 1]) {
max = Math.max(max, sum[k + 1] - sum[j + 1] + dfs(memo, k + 1, j, sum));
} else if (sum[i] - sum[k + 1] < sum[k + 1] - sum[j + 1]) {
max = Math.max(max, sum[i] - sum[k + 1] + dfs(memo, i, k, sum));
} else {
max = Math.max(max, Math.max(sum[k + 1] - sum[j + 1] + dfs(memo, k + 1, j, sum), sum[i] - sum[k + 1] + dfs(memo, i, k, sum)));
}
}
return memo[i][j] = max;
}
}
9. 石子游戏 VI
class Solution {
public int stoneGameVI(int[] aliceValues, int[] bobValues) {
int n = aliceValues.length;
Integer[] nums = new Integer[n];
List<Map.Entry<Integer, Integer>> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
nums[i] = aliceValues[i] + bobValues[i];
list.add(new HashMap.SimpleEntry<Integer, Integer>(i, nums[i]));
}
Collections.sort(list, (a, b) -> b.getValue() - a.getValue());
int aRes = 0;
int bRes = 0;
for (int i = 0; i < n; i++) {
if (i % 2 == 0) {
aRes += aliceValues[list.get(i).getKey()];
} else {
bRes += bobValues[list.get(i).getKey()];
}
}
if (aRes > bRes) {
return 1;
} else if (aRes < bRes) {
return -1;
} else {
return 0;
}
}
}
10. 石子游戏 VII
class Solution {
public int stoneGameVII(int[] stones) {
int n = stones.length;
int[][] memo = new int[n][n];
int[] sum = new int[n + 1];
for (int i = n - 1; i >= 0; i--) {
if (i == n - 1) {
sum[i] = stones[i];
} else {
sum[i] = stones[i] + sum[i + 1];
}
}
return dfs(sum, 0, n - 1, memo);
}
private int dfs(int[] sum, int i, int j, int[][] memo) {
if (i >= j) {
return 0;
}
if (memo[i][j] != 0) {
return memo[i][j];
}
int res = Integer.MIN_VALUE;
res = Math.max(sum[i+1]-sum[j+1] - dfs(sum , i+1,j,memo) , sum[i]-sum[j] - dfs(sum , i,j-1,memo));
return memo[i][j]=res;
}
}
11. 如果相邻两个颜色均相同则删除当前颜色
class Solution {
public boolean winnerOfGame(String cs) {
int alice = 0;
int bob = 0;
int n = cs.length();
for (int i = 1; i < n - 1; i++) {
if (cs.charAt(i) == 'A' && cs.charAt(i - 1) == 'A' && cs.charAt(i + 1) == 'A') {
alice++;
}
if (cs.charAt(i) == 'B' && cs.charAt(i - 1) == 'B' && cs.charAt(i + 1) == 'B') {
bob++;
}
}
if (alice <= bob) {
return false;
}
return true;
}
}
12. 你可以获得的最大硬币数目
class Solution {
public int maxCoins(int[] piles) {
Arrays.sort(piles);
int n = piles.length;
int res = 0;
int idx = n - 2;
for (int i = 0; i < n / 3; i++) {
res += piles[idx];
idx -= 2;
}
return res;
}
}
13. 求和游戏
class Solution {
public static boolean sumGame(String num) {
int n = num.length();
int alice = 0, aliceNum = 0;
int bob = 0, bobNum = 0;
for (int i = 0; i < n / 2; i++) {
if (num.charAt(i) == '?') {
aliceNum++;
} else {
alice += num.charAt(i) - '0';
}
if (num.charAt(i+n/2) == '?') {
bobNum++;
} else {
bob += num.charAt(i+n/2) - '0';
}
}
if ((alice - bob) * 2 == 9 * (bobNum - aliceNum)) {
return false;
}
return true;
}
}