Coins in a Line I Solution
第一个游戏者永远拿不到第3n枚硬币,所以在硬币总数不能被3整除的情况下,都可以赢。
public class Solution {
public boolean firstWillWin(int n) {
return n % 3 != 0;
}
}
Coins in a Line II
Problem
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.
Note
DP做法,设dp[i]为第一个游戏者从第i枚硬币到end能获得硬币价值的最大值。
Solution
Fool Lintcode method: it happened to work! But it's completely wrong!
public class Solution {
public boolean firstWillWin(int[] A) {
// write your code here
if (A == null) return false;
int sum = 0;
for (int i = 1; i <= A.length / 3; i++) {
sum += A[3*i-1];
}
int total = 0;
for (int i = 0; i < A.length; i++) {
total += A[i];
}
if (sum * 2 > total) return false;
return true;
}
}
DP method
主要参考这篇文章的解释
public class Solution {
public boolean firstWillWin(int[] values) {
// write your code here
int len = values.length;
if (len <= 2) {
return true;
}
//dp[i] means the largest value you(the first player)
//can get when you start from values[i]
int[] dp = new int[len+1];
//not even exist
dp[len] = 0;
//when you happen to have the last coin, yes, consider the last first
dp[len-1] = values[len-1];
//sure we should get the last two for most value
dp[len-2] = values[len-1] + values[len-2];
//same rules, why leave two(len-1, len-2) for the other player
dp[len-3] = values[len-2] + values[len-3];
//next we are gonna sum up
for (int i = len-4; i >= 0; i--) {
//you have to have values[i] and the non-optimal later choice
//because the other player is smart to leave you the worse one
//between two of your optimal choices
dp[i] = values[i] + Math.min(dp[i+2], dp[i+3]);
dp[i] = Math.max(dp[i], values[i] + values[i+1] + Math.min(dp[i+3], dp[i+4]));
//equals to: dp[i] = Math.max(values[i] + Math.min(dp[i+2],dp[i+3]), values[i] + values[i+1] + Math.min(dp[i+3], dp[i+4]));
}
//compute the total value of coins
int sum = 0;
for (int a: values) {
sum += a;
}
//compare your final value to the other player's
return dp[0] > sum - dp[0];
}
}
Now let's make the code elegant
public class Solution {
public boolean firstWillWin(int[] values) {
if (values == null || values.length == 0) return false;
int n = values.length;
if (n < 3) return true;
int[] dp = new int[n+1];
dp[n] = 0;
dp[n-1] = values[n-1];
dp[n-2] = values[n-1]+values[n-2];
dp[n-3] = values[n-2]+values[n-3];
for (int i = n-4; i >= 0; i--) {
dp[i] = Math.max(values[i] + Math.min(dp[i+2], dp[i+3]), values[i] + values[i+1] + Math.min(dp[i+3], dp[i+4]));
}
int sum = 0;
for (int v: values) sum += v;
return dp[0] > sum - dp[0];
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。