代码改变世界

[LintCode] 395. Coins in a Line 2_Medium tag: Dynamic Programming, 博弈

2018-07-26 00:34  Johnson_强生仔仔  阅读(323)  评论(0编辑  收藏  举报

Description

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.

 

这个题目思路实际上跟[LintCode] 394. Coins in a Line_ Medium tag:Dynamic Programming_博弈很像, 然后博弈类的如果要取最大值, 需要用minmax算法, 得到关系式

A[i] = max(min(ans[i-2], ans[i-3]) + values[n-i], min(ans[i-3], ans[i-4] + values[n-i] + values[n-i+1])) ,

第一个就是只选1个coin, 第二个就是选两个coins, 最后return ans[n] > sum(values) //2

 

1. Constraints

1) values 长度大于等于0

2) element 是大于0 的integer

 

2. Ideas

Dynamic Programming      T: O(n)           S; O(n)  optimal  O(1)

 

3. Code

1) S; O(n)

class Solution:
    def coinsInLine2(self, values):
        ans = [0]*5
        ans[1]= values[0]
        ans[2] = ans[3] = sum(values[:2])
        n = len(values)
        if n < 4: return ans[n] > sum(values) //2
        ans[4] = values[0] + max(values[1], values[3])
        ans = ans + [0]*(n-4)
        for i in range(5, n+1):
            ans[i] = max(min(ans[i-2], ans[i-3]) + values[n-i], min(ans[i-3], ans[i-4]) + values[n-i] + values[n-i+1])
        return ans[n] > sum(values)//2

 

2) 可以用滚动数组方式将Space降为O(1)

 

4. Test cases 

1) [1,5,2,10]