LintCode Coins in a line III
There are n coins in a line. Two players take turns to take a coin from one of the ends of the line until there are no more coins left. The player with the larger amount of money wins.
Could you please decide the first player will win or lose?Example
Given array A = [3,2,2], return true.
Given array A = [1,2,4], return true.
Given array A = [1,20,4], return false.
Recursion + Memorization
复杂度
O(N^2), O(N^2)
思路
参考coins II的思路,对于dpi,表示在从i到j的范围内,先手玩家能拿到的最大的硬币价值。
对于状态dpi,先手玩家有两种选择, 要么拿num[i]的硬币,要么拿num[j]的硬币(左边一个的或者右边一侧的),
如果拿左侧的硬币,dpi = num[i] + sumi + 1 - dpi + 1
如果拿右侧的硬币,dpi = num[j] + sumi - dpi
取两个值的最大值。
也可以用dp写。
for(int k = 2; k < len; k ++) {
for(int i = 0; i < len - k; i ++) {
int right = i + k;
dp[i][right] = Math.max();
}
}
代码
int len;
Map<Integer, Integer> map = new HashMap<>();
public boolean coins(int[] num) {
len = num.length;
int[] sum = new int[len];
for(int i = 0; i < len; i ++) {
if(i == 0) sum[i] = num[i];
else sum[i] = num[i] + sum[i - 1];
}
return helper(num, 0, len - 1, sum) * 2 > sum[len - 1];
}
public int helper(int[] num, int left, int right, int[] sum) {
// base case;
if(left > right) return 0;
if(left == right) return num[left];
if(map.containsKey(left * len + right)) return map.get(left * left + right);
//
int val = Math.max(num[left] + getSum(left + 1, right, sum) - helper(num, left + 1, right, sum), num[right] + getSum(left, right - 1, sum) - helper(num, left, right - 1, sum));
map.put(left * len + right, val);
return val;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。