美文网首页
Coins in a line III

Coins in a line III

作者: Star_C | 来源:发表于2018-04-06 23:13 被阅读0次

    Question

    from lintcode
    There are n coins in a line. Two players take turns to take a coin from one of the two 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.

    Idea

    We want to know if the first player can win, i.e. if he can win in the case where

    • he tries to get the maximum amount as he can
    • the second player tries to minimize his income as possible
    
    /**
     *  maxTotal[left][right] means the maximum amount that the first player
     *  can have.
     *
     *  see calculate() for the dynamic programming function
     */
    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) {
    
            if (values.length == 0) return false;
    
            int n = values.length;
            int[][] maxTotal = new int[n][n];
            boolean[][] calculated =new boolean[n][n];
    
            int sum = 0;
            for(int now : values)
                sum += now;
    
            return sum < 2* calculate(0,values.length - 1, maxTotal, calculated, values);
        }
    
        int calculate(int left, int right, int [][]maxTotal, boolean [][]calculated, int []values) {
    
            if(calculated[left][right])
                return maxTotal[left][right];
    
            calculated[left][right] = true;
    
            if (left == right) {
                maxTotal[left][right] = values[left];
            } else if(left + 1 == right) {
                maxTotal[left][right] = Math.max(values[left], values[right]);
            } else {
    
                int  firstPlayerPickLeft = values[left] +
                        // why Math.min? cuz it's opponent's turn, whose goal is to make the first player lose
                        Math.min(
                            // opponent picks left element of the remained list
                            calculate(left + 2, right, maxTotal, calculated, values),
                            // opponent picks right element of the remained list
                            calculate(left + 1, right - 1, maxTotal, calculated, values)
                        );
    
                int  firstPlayerPickRight = values[right] +
                        // why Math.min? cuz it's opponent's turn, whose goal is to make the first player lose
                        Math.min(
                                // opponent picks left element of the remained list
                                calculate(left, right - 2, maxTotal, calculated, values),
                                // opponent picks right element of the remained list
                                calculate(left + 1, right - 1, maxTotal, calculated, values)
                        );
    
                maxTotal[left][right] = Math.max(firstPlayerPickLeft, firstPlayerPickRight);
            }
    
            return maxTotal[left][right];
        }
    }
    

    相关文章

      网友评论

          本文标题:Coins in a line III

          本文链接:https://www.haomeiwen.com/subject/rkkehftx.html