Coins in a Line I
There are n coins in a line. Two players take turns to take one or two coins from right side until there are no more coins left. The player who take the last coin wins.
Could you please decide the first play will win or lose?
Example
n = 1
, return true
.
n = 2
, return true
.
n = 3
, return false
.
n = 4
, return true
.
n = 5
, return true
.
分析:
既然可以拿1个和2个,那么只要coin的个数能够被3整除,那么第一个拿的百分百会输掉。
1 public class Solution { 2 /** 3 * @param n: an integer 4 * @return: a boolean which equals to true if the first player will win 5 */ 6 public boolean firstWillWin(int n) { 7 // write your code here 8 if (n % 3 == 0) return false; 9 return true; 10 } 11 }
Coins in a Line II
There are n coins with different value in a line. Two players take turns to take one or two coins from left side until there are no more coins left. The player who take the coins with the most value wins.
Could you please decide the first player will win or lose?
Example
Given values array A = [1,2,2]
, return true
.
Given A = [1,2,4]
, return false
.
分析:
这里假设两个player都是rational player,也就是说两个人都会采取最优策略。
那么,这个最优策略怎么来的,对于当前player,他要么选取一个,或者两个,选取一个只能在下面两种情况中产生,假设当前index 为 i;
1. A[i] >= A[i + 1] + A[i + 2];
2. A[i + 1] + A[i + 2] - A[i] <= A[i + 2] + A[i + 3] - A[i] - A[i + 1]
选取两个这种策略只能在下面两种情况中产生:
1. A[i] + A[i + 1] >= A[i + 2] + A[i + 3];
2. A[i + 1] + A[i + 2] - A[i] > A[i + 2] + A[i + 3] - A[i] - A[i + 1]
1 public class Solution { 2 /** 3 * @param values: an array of integers 4 * @return: a boolean which equals to true if the first player will win 5 */ 6 public boolean firstWillWin(int[] values) { 7 if (values.length <= 2) return true; 8 int[] total = new int[2]; 9 10 boolean firstPlayerTurn = true; 11 int i = 0; 12 while (i < values.length) { 13 if (i + 3 >= values.length) { 14 if (i < values.length) { 15 increase(values, i, total, firstPlayerTurn); 16 i++; 17 } 18 if (i < values.length) { 19 increase(values, i, total, firstPlayerTurn); 20 i++; 21 } 22 } else { 23 if (values[i] >= values[i + 1] + values[i + 2]) { 24 increase(values, i, total, firstPlayerTurn); 25 i++; 26 } else if (values[i] + values[i + 1] >= values[i + 2] + values[i + 3]) { 27 increase(values, i, total, firstPlayerTurn); 28 i++; 29 increase(values, i, total, firstPlayerTurn); 30 i++; 31 } else { 32 int diff1 = values[i + 1] + values[i + 2] - values[i]; 33 int diff2 = values[i + 2] + values[i + 3] - values[i] - values[i + 1]; 34 if (diff1 < diff2) { 35 increase(values, i, total, firstPlayerTurn); 36 i++; 37 } else { 38 increase(values, i, total, firstPlayerTurn); 39 i++; 40 increase(values, i, total, firstPlayerTurn); 41 i++; 42 } 43 } 44 } 45 if (firstPlayerTurn) { 46 firstPlayerTurn = false; 47 } else { 48 firstPlayerTurn = true; 49 } 50 } 51 return total[0] > total[1]; 52 } 53 54 public void increase(int[] values, int index, int[] total, boolean firstPlayer) { 55 if (firstPlayer) { 56 total[0] += values[index]; 57 } else { 58 total[1] += values[index]; 59 } 60 } 61 }