395.Coins in a Line II-硬币排成线 II(中等题)

硬币排成线 II

  1. 题目

    有 n 个不同价值的硬币排成一条线。两个参赛者轮流从左边依次拿走 1 或 2 个硬币,直到没有硬币为止。计算两个人分别拿到的硬币总价值,价值高的人获胜。

    请判定 第一个玩家 是输还是赢?

  2. 样例

    给定数组 A = [1,2,2], 返回 true.
    给定数组 A = [1,2,4], 返回 false.

  3. 题解

    1.若第一个玩家取values[i],则对方可以取values[i+1]或values[i+1]+values[i+2]。当对方取values[i+1]后,第一个玩家只能从[i+2,n]中取,我们所取得最大值是dp[i+2]。当对方取values[i+1]+values[i+2]后,则只能从[i+3,n]中取,最大值是dp[i+3],即dp[i]=values[i]+min(dp[i+2],dp[i+3])。

    2.若第一个玩家取values[i]+values[i+1],则对方可取values[i+2]或values[i+2]+values[i+3]。当对方取values[i+2]后,第一个玩家只能从[i+3,n]中取,我们取得最大值是dp[i+3]。当对方取values[i+2]+values[i+3]后,则只能从[i+4,n]中取,最大值是dp[i+4],即dp[i]=values[i]+values[i+1]+min(dp[i+3],dp[i+4])。

public class Solution {
    /**
     * @param values: an array of integers
     * @return: a boolean which equals to true if the first player will win
     */
    public boolean firstWillWin(int[] values) {
        int n = values.length;  
        if (n < 3)  
        {  
            return true;  
        }  
        //dp[i]表示从i到最后一个元素能取到的最大值
        int dp[] = new int[n+1];  
        dp[n] = 0;  
        dp[n-1] = values[n-1];  
        dp[n-2] = values[n-2] + values[n-1];  
        dp[n-3] = values[n-3] + values[n-2];  

        int sum = values[n-3] + values[n-2] + values[n-1];  
        for (int i = n-4; i >= 0; i--)  
        {  
            int a = values[i] + Math.min(dp[i+2], dp[i+3]);  
            int b = values[i] + values[i+1] + Math.min(dp[i+3], dp[i+4]);  
            dp[i] = Math.max(a, b);  
            sum += values[i];  
        }  

        return dp[0] > sum-dp[0];  
    }
}

Last Update 2016.11.13

你可能感兴趣的:(LintCode笔记)